diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000000..adb1f24543 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,42 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Overview + +This is the Docusaurus 3 site for [docs.sleakops.com](https://docs.sleakops.com), edited via Sveltia CMS. Content lives under `content/docs//
/`, `content/tutorials//`, and `content/changelog//`. For the full writing style guide (voice, doc article vs tutorial structure, FAQ format, tags, image conventions), see `.claude/skills/sleakops-docs` — this file only covers repo mechanics. + +## Development Commands + +```bash +make install # yarn install (via docker compose) +make run # docker compose up -d — dev server on :4000 (English content) +make run-es # dev server with locale=es +make build # production build, all locales +make build-en / make build-es # single-locale build +make serve # serve the production build locally +make collections # regenerate Sveltia CMS config.yml from the content/ folder structure +make tutorials # regenerate tutorials-generated.json from tutorial MDX files +make clear # clear Docusaurus cache +``` + +**Always start via `yarn start`/`make run`, never `npx docusaurus start` directly.** The `prestart`/`prebuild` npm hooks run `sync_content.js`, which builds the symlinks Docusaurus actually reads (`docs/ → content/docs/en`, `i18n/es/docusaurus-plugin-content-docs/current/ → content/docs/es`, etc.) from the CMS-friendly `content///` structure. Skipping the hook leaves stale or broken symlinks and the dev server fails with "the docs folder does not exist". + +Other repo scripts run as part of those hooks — `clean_frontmatter.js` (strips empty frontmatter fields that fail validation), `cleanup_cms_temp.js` (removes Sveltia's temp hex-named folders), `generate_tutorials.js` (builds the tutorials showcase index), `fix_links.js` (one-off ES link-prefix repair, not part of the normal hook chain). + +The Docusaurus dev server does not SSR content in dev mode (`view-source` just shows an empty `
` shell) — verifying rendered output requires a real browser, not `curl`. + +## FAQ `
`/`` gotcha + +Docusaurus's `
` component looks for a `` element among its JSX children to use as the disclosure title. If ``, its text, and `` are collapsed onto **one line**, MDX parses it in a way that breaks that lookup, and the component silently falls back to the literal placeholder text **"Details"** instead of showing the question. Always split it across separate lines: + +```mdx +
+ + ### Your question here? + + Your answer. +
+``` + +not `### Your question here?` on a single line. diff --git a/content/docs/en/cli.mdx b/content/docs/en/cli.mdx index c57d25d5a7..712c01763f 100644 --- a/content/docs/en/cli.mdx +++ b/content/docs/en/cli.mdx @@ -55,15 +55,15 @@ As previously mentioned the key might be an input here or a environment variable Also, you might mark if you want the process to **wait** the build to be finished or not. -When you use **wait**, you can also set a **timeout** (in minutes) to cap how long the CLI waits for the build to finish. It defaults to **180 minutes**; pass `0` to wait indefinitely. You can also set it through the `BUILD_TIMEOUT_MINUTES` environment variable. +You can set a **timeout** (in minutes) for a build. This is the build's maximum lifetime on the backend: if the build runs longer, SleakOps stops it and marks it as failed, so a stuck build can't hang forever. It defaults to **180 minutes**, and every build is bounded even if you don't pass it. When you also use **wait**, `--timeout` caps how long the CLI watches the build too. The CLI's default can be set through the `BUILD_TIMEOUT_MINUTES` environment variable. | **Option** | **Description** | | ------------- | --------------------------------------------------------------------------- | | **--wait** | Wait for the build to finish before returning. | -| **--timeout** | Minutes to wait when using `--wait`. Default `180`. Use `0` for no timeout. | +| **--timeout** | Maximum build lifetime in minutes; also caps how long the CLI watches with `--wait`. Default `180`. `0` keeps the platform default and lets `--wait` watch indefinitely. | :::tip -The timeout is client-side: it controls how long the CLI watches the build, not the build itself on the backend. When it expires, the CLI prints a message and exits with code `1`, so a stuck build fails your CI pipeline instead of silently passing. +`--timeout` works on two levels: the backend stops the build once it exceeds the limit (this happens for every build, even without `--wait`), and — when you pass `--wait` — the CLI also stops watching after the same time and exits with code `1`, so a stuck build fails your CI pipeline instead of hanging. ::: ### 3. Make a Deploy @@ -78,6 +78,31 @@ SleakOps seamlessly handles the deployment process, ensuring that your applicati Here **project** and **environment** are the required arguments. User might add a **build** or **tag** image to specify an image. Here the **wait** and **key** options are present to, the usage is the same as in the build command. +### Injecting values on deploy + +You can inject Helm values into a single deployment, on top of everything configured in the platform (see [Values](/docs/project/values) for the override levels): + +```plain +sleakops deploy -p myapp -e prod -f values.prod.yaml +sleakops deploy -p myapp -e prod --set api_web.replicas=3 +cat values.yaml | sleakops deploy -p myapp -e prod -f - +``` + +| **Option** | **Description** | +| ---------------- | --------------------------------------------------------------------------------------------------------- | +| **-f, --values** | YAML file with values for this deploy (repeatable; `-` reads stdin; later files win). | +| **--set** | Set a single value, `key.path=value` (repeatable; wins over `-f`). YAML coercion applies: `5` → int, `true` → bool. | +| **--set-string** | Like `--set` but the value is always kept as a string (no coercion). | + +:::warning Ephemeral by design +Deploy-time values apply to **that deployment only** — they win over every value configured in the platform, and the next deploy without `-f`/`--set`/`--set-string` reverts to the platform values. They are the right tool for one-off tweaks, not for durable configuration: make durable changes at the project or workload level instead. +::: + +Two caveats: + +- **For secrets prefer `-f`** (or stdin): `--set` and `--set-string` arguments stay in your shell history and CI logs. +- **Two different list semantics**: between your own inputs (`-f` files and `--set` flags) a list replaces the previous one, exactly like Helm. But when your deploy values merge against the platform levels, lists are **combined** instead of replaced — an entry you pass is added to the generated ones, it doesn't drop them. + ## CI/CD Examples With SleakOps CLI, you can integrate your CI/CD pipelines, automate the build and deployment process, and focus on delivering exceptional applications without the hassle of manual intervention. diff --git a/content/docs/en/domain/delegation.mdx b/content/docs/en/domain/delegation.mdx index 571a4f8899..f0e1bfc9f2 100644 --- a/content/docs/en/domain/delegation.mdx +++ b/content/docs/en/domain/delegation.mdx @@ -69,7 +69,9 @@ ns-012.awsdns-01.co.uk ### Common Registrars
-GoDaddy + +GoDaddy + 1. Go to [Domain Manager](https://account.godaddy.com/products) 2. Click on your domain @@ -81,7 +83,9 @@ ns-012.awsdns-01.co.uk
-Namecheap + +Namecheap + 1. Go to [Domain List](https://ap.www.namecheap.com/domains/list/) 2. Click "Manage" next to your domain @@ -92,7 +96,9 @@ ns-012.awsdns-01.co.uk
-Cloudflare + +Cloudflare + **Note:** If using Cloudflare, you must disable Cloudflare proxy for proper delegation. diff --git a/content/docs/en/project/build/build.mdx b/content/docs/en/project/build/build.mdx index 222ac8fd69..9d99c4d18e 100644 --- a/content/docs/en/project/build/build.mdx +++ b/content/docs/en/project/build/build.mdx @@ -31,6 +31,34 @@ SleakOps has its own CLI Tool that you can use to automate Builds and Deployment ::: +## Build timeout + +Every build runs with a maximum lifetime. If a build gets stuck — waiting on a lock, pulling an image that never becomes available, or looping inside a build step — SleakOps stops it automatically and marks it as failed instead of letting it run forever. When you don't set a limit, a platform default of 180 minutes applies, so every build is always bounded. + +Set the limit per build from the [SleakOps CLI](/docs/cli) with the `--timeout` flag, in minutes: + +```bash +sleakops build --project my-app --branch main --timeout 30 +``` + +| **`--timeout` value** | **Effect** | +| --------------------- | --------------------------------------------------------------------------------------- | +| **Omitted** | The platform default of 180 minutes applies. | +| **A positive number** | The build is stopped and marked as failed after that many minutes. | +| **`0`** | The build is still bounded by the platform default. With `--wait`, it also removes the CLI's wait cap, so the CLI polls until the build finishes; without `--wait` it behaves like omitting `--timeout`. | + +When combined with `--wait`, `--timeout` also caps how long the CLI waits for the build to finish before exiting with an error. This is useful in CI/CD pipelines, where a stuck build would otherwise block the job indefinitely: + +```bash +sleakops build --project my-app --branch main --wait --timeout 30 +``` + +If the build hasn't finished within the timeout, the CLI exits with a non-zero status so the pipeline step fails fast. + +:::tip +For CI/CD, set `--timeout` to a value slightly above your normal build duration. That way a genuinely stuck build is caught quickly, while healthy builds always have room to finish. +::: + ## FAQs
diff --git a/content/docs/en/project/chart/extra_templates.mdx b/content/docs/en/project/chart/extra_templates.mdx index 5670ca10fd..acfe64739a 100644 --- a/content/docs/en/project/chart/extra_templates.mdx +++ b/content/docs/en/project/chart/extra_templates.mdx @@ -7,6 +7,10 @@ import { FiExternalLink } from "react-icons/fi"; # Extra Templates +:::warning Deprecated in favor of Manifests +Extending templates & values is deprecated. To add or edit custom resources, use the Project's **Manifests** section instead — each resource becomes its own manifest, with validation, preview and per-Workload scoping. See the [Manifests documentation](/docs/project/manifests). Existing Extra Templates keep deploying as before until you migrate them. +::: + Extra Templates enable you to deploy custom Kubernetes resources beyond SleakOps' built-in components. This powerful feature allows you to extend your project with specialized resources such as custom Ingresses, testing pods, or other Kubernetes objects tailored to your specific requirements. ## Use Cases diff --git a/content/docs/en/project/chart/index.mdx b/content/docs/en/project/chart/index.mdx index 27377352b5..3dcd58202b 100644 --- a/content/docs/en/project/chart/index.mdx +++ b/content/docs/en/project/chart/index.mdx @@ -69,30 +69,40 @@ Values that apply across the entire Project: ## Frequently Asked Questions
- ### Where can I find my Project's Chart? + + ### Where can I find my Project's Chart? + Currently, Charts are not viewable directly in the platform. However, you can download the Chart from the ECR repository created for your Project in the corresponding AWS Account.
- ### Can I modify the Chart deployed by a Project? - Yes, with some limitations. You can: - Add custom templates using [**Extra - Templates**](/docs/project/chart/extra_templates) - Add chart dependencies using [**Chart - Dependencies**](/docs/project/chart/chart_dependencies), similar to [Helm Chart Dependencies{" "} - - ](https://helm.sh/docs/helm/helm_dependency/) + + ### Can I modify the Chart deployed by a Project? + + Yes. You can: + + - Customize or add [**Manifests**](/docs/project/manifests) per Workload or shared across the Project + - Override [**Values**](/docs/project/values) at the project or workload level + - Add chart dependencies using [**Chart Dependencies**](/docs/project/chart/chart_dependencies), similar to [Helm Chart Dependencies ](https://helm.sh/docs/helm/helm_dependency/)
- ### Can I add a custom Ingress to my Project? - Yes, this is one of the primary use cases for the **Extra Templates** feature. - See the [Extra Templates documentation](/docs/project/chart/extra_templates) for detailed - instructions. + + ### Can I add a custom Ingress to my Project? + + Yes — add it as a manifest from the Workload's Advanced view or the project + bucket. See the [Manifests documentation](/docs/project/manifests). The legacy + [Extra Templates](/docs/project/chart/extra_templates) path still works but is + deprecated.
- ### Can I modify existing Kubernetes Service templates? - No, modifying SleakOps built-in templates is not currently supported. We are - working on enabling modifications to built-in templates in future releases. + + ### Can I modify existing Kubernetes Service templates? + + Yes. Open the Workload's **Advanced** view, click the manifest and edit its + YAML — your copy is preserved and never overwritten by SleakOps. See + [Manifests](/docs/project/manifests).
diff --git a/content/docs/en/project/dependency/index.mdx b/content/docs/en/project/dependency/index.mdx index 8b8e20cc31..addfe0bfc6 100644 --- a/content/docs/en/project/dependency/index.mdx +++ b/content/docs/en/project/dependency/index.mdx @@ -45,17 +45,23 @@ These dependencies integrate seamlessly with SleakOps, providing a comprehensive
- ### Can the same dependency be used for multiple Projects? + + ### Can the same dependency be used for multiple Projects? + At the moment this is not possible, you need one dependency per each project.
- ### How do I delete a Dependency? + + ### How do I delete a Dependency? + By accessing the *Dependency Listing* and clicking the delete option.
- ### What happens when I delete a dependency? + + ### What happens when I delete a dependency? + By deleting a dependency, SleakOps will remove all the information related to it and all what is related to it will stop working. To solve that SleakOps create a Deployment in PENDING_APPROVAL status, that must be run manually ASAP @@ -106,3 +112,70 @@ To move forward choose between the following guides. [Memcached](/docs/project/dependency/memcached-aws). [OpenSearch](/docs/project/dependency/opensearch-aws). [SQS](/docs/project/dependency/sqs-aws). + +## Dependency Access + +Dependency access refers to the security and connectivity mechanisms that let your application's workloads interact securely with external dependencies. SleakOps automatically manages these access patterns to ensure secure communication between your services and their dependencies. + +### Access Management + +#### Automatic Service Account Configuration +When you create a dependency, SleakOps automatically: +- **Creates IAM roles** with appropriate permissions for the specific dependency type +- **Configures service accounts** in your Kubernetes namespace +- **Establishes secure connections** between your workloads and the dependency +- **Manages credentials** through Kubernetes secrets and IAM roles + +#### Network Security +- **VPC Integration**: Dependencies are created inside your project's VPC for secure network access +- **Security Groups**: Automatically configured to allow the traffic needed between services +- **Private Endpoints**: Dependencies use private endpoints when available to minimize exposure + +### Access Patterns + +#### Database Access +For database dependencies (MySQL, PostgreSQL, etc.): +- **Connection Strings**: Automatically generated and stored as Kubernetes secrets +- **Authentication**: Managed through IAM roles and database-specific credentials +- **SSL/TLS**: Encrypted connections are configured by default +- **At-Rest Encryption**: Enabled by default on new dependencies + - You can turn it off or configure your own KMS key when you create it + - Aurora (PostgreSQL/MySQL) is always encrypted, with no way to opt out + - If the dependency was created before this improvement shipped, check the specific case: it may not be encrypted +- **Connection Pooling**: Optimized connection management for better performance + +#### Cache Access +For caching services (Redis, Memcached): +- **Endpoint Configuration**: Automatically configured in your application's environment +- **Authentication**: Secure access through IAM roles and service-specific credentials +- **Network Policies**: Access restricted to authorized workloads only + +#### Storage Access +For storage services (S3, etc.): +- **Bucket Policies**: Automatically configured with least-privilege access +- **IAM Permissions**: Service accounts receive only the permissions they need +- **Access Keys**: Managed through AWS IAM roles for greater security + +### Security Best Practices + +#### Principle of Least Privilege +- **Minimal Permissions**: Dependencies receive only the minimum required permissions +- **Resource-Specific Access**: Access is scoped to specific resources whenever possible +- **Regular Audits**: SleakOps provides tools to review and audit dependency access + +#### Credential Management +- **Automatic Rotation**: Credentials are rotated automatically when possible +- **Secure Storage**: All credentials are stored as Kubernetes secrets +- **No Hardcoded Secrets**: Applications access dependencies through environment variables + +:::info Access Monitoring +SleakOps provides monitoring and logging capabilities to track dependency access patterns, helping you identify potential security issues and optimize performance. +::: + +:::tip Troubleshooting Access Issues +If you run into access issues with dependencies: +1. Check the dependency's status in the SleakOps console +2. Confirm your workload has the correct service account +3. Review the IAM role permissions for the dependency +4. Verify network connectivity and security group configurations +::: diff --git a/content/docs/en/project/dependency/oracle-aws.mdx b/content/docs/en/project/dependency/oracle-aws.mdx index 287ac0ec80..47eb754efd 100644 --- a/content/docs/en/project/dependency/oracle-aws.mdx +++ b/content/docs/en/project/dependency/oracle-aws.mdx @@ -12,14 +12,18 @@ SleakOps facilitates the integration of Oracle databases through Amazon RDS (Rel ## FAQs
- ### License + + ### License + When creating an Oracle DB using Sleakops License Included (LI). Currently Bring Your Own License (BYOL) is not supported, however, contact support for more information.
- ### How does SleakOps manage Oracle credentials? + + ### How does SleakOps manage Oracle credentials? + When you create an Oracle dependency in SleakOps, it automatically generates a Vargroup for your database. This Variable Group securely stores the Oracle credentials and other important configuration details, such as the database @@ -28,7 +32,9 @@ SleakOps facilitates the integration of Oracle databases through Amazon RDS (Rel
- ### What is Multi-AZ deployment and should I enable it? + + ### What is Multi-AZ deployment and should I enable it? + Multi-AZ (Availability Zone) deployment ensures high availability and failover support by replicating your database in another availability zone. It's recommended for production environments to prevent downtime. Keep in mind that diff --git a/content/docs/en/project/deployment/index.mdx b/content/docs/en/project/deployment/index.mdx index a917019f31..7427f12321 100644 --- a/content/docs/en/project/deployment/index.mdx +++ b/content/docs/en/project/deployment/index.mdx @@ -13,7 +13,7 @@ A Deployment in Sleakops signifies the installation of a new version of your app :::info -When there's an update to any of these resources, Sleakops will notify you about a Deployment via the unpublished banner shown [below](#unpublished-banner). +When there's an update to any of these resources that wasn't deployed immediately, SleakOps queues it as a [pending change](/docs/project/deployment/pending_changes) and shows a **Publish** badge on the environment. ::: @@ -41,12 +41,9 @@ If you skip deploying your changes immediately, or if your modification doesn't -#### Unpublished banner +#### Pending changes -- Unpublished Changes Banner: This banner is shown when there's content pending that was not yet deployed on the cluster. Through this banner, you have the choice to deploy only the VariableGroups or if you want to deploy everything, including the Services in the 'draft' state. - - DEPLOY-deploy-changes-banner - +- **Publish badge**: environments with content pending that was not yet deployed on the cluster show a **Publish** badge in the Projects list, the Project dashboard and the Deployments list. Clicking it opens the pending deployment's detail, where you review the accumulated changes and publish them. See [Pending Changes & Publishing](/docs/project/deployment/pending_changes). - Via the [CLI ](/docs/cli). \ No newline at end of file diff --git a/content/docs/en/project/deployment/pending_changes.mdx b/content/docs/en/project/deployment/pending_changes.mdx new file mode 100644 index 0000000000..1d804f8cd1 --- /dev/null +++ b/content/docs/en/project/deployment/pending_changes.mdx @@ -0,0 +1,83 @@ +--- +sidebar_position: 3 +--- +import Zoom from "react-medium-image-zoom"; +import "react-medium-image-zoom/dist/styles.css"; + +# Pending Changes & Publishing + +Not every change has to hit the cluster immediately. Whenever you save an edit with the **Deploy?** switch off — a Workload edit, a [manifest](/docs/project/manifests) customization, a [values](/docs/project/values) override, a Var Group update — SleakOps records it as a **pending change** instead of deploying it. Pending changes accumulate per environment until you review and publish them with one click. + +## How changes accumulate + +Each Project environment holds **at most one pending Release and one pending Deployment**: + +- Changes that affect the chart — Workloads, manifests, chart dependencies — create or update the pending **Release**, re-calculating its version and appending a line to the change list, with a pending **Deployment** pointing to it. +- Var Group changes only queue the pending **Deployment**: they update values, so the environment's current Release is reused instead of cutting a new chart version. +- Versions follow the chart's semver: creating or deleting a Workload bumps the *minor*; edits to Workloads, manifests or chart dependencies bump the *patch*. +- Publication is always manual — SleakOps never auto-approves pending changes. +- If someone triggers a direct deployment in the meantime, it **supersedes** the pending one: the pending Release and Deployment are discarded so the environment never carries stale queued changes. + +## The Publish badge + +Environments with pending changes show a pink **Publish** badge: + + + Projects list with the Publish badge on an environment with pending changes + + +The badge appears in three places: + +- The **Projects** list, on each environment row with pending changes. +- The **Project dashboard** header. +- The **Deployments** list, on the deployment whose state is `Pending Approval`. + +## Review and publish + +Clicking the badge opens the pending deployment's detail. The **Pending Changes** section lists every accumulated change, along with the pending Release version and how long ago the queue started: + + + Deployment detail with the Pending Changes section and the Publish button + + +Press **Publish** to launch it. SleakOps publishes the pending chart Release (when there is one) and chains the deployment right after — you can follow its progress in the [Deployments](/docs/project/deployment) section. The badges disappear as soon as the deployment leaves the `Pending Approval` state. + +:::info Permissions +Viewers can open the detail and read the pending changes, but only editors and admins can publish. The Publish button is also hidden when you're browsing an account in read-only mode. +::: + +## FAQs + +
+ +### What creates a pending change? + +Any edit saved with the Deploy? switch off: Workload create/edit/delete, manifest customizations and additions, values overrides, Var Group changes and chart dependency updates. Edits saved with the switch on deploy immediately instead. +
+ +
+ +### Can I discard pending changes? + +There is no explicit discard. Triggering a direct deployment (for example from a Build, or via the CLI) supersedes the pending Release and Deployment with the current state of the environment. +
+ +
+ +### What if new changes appear after I publish? + +Publishable changes made between the publish and the actual deploy cancel the deployment with a message asking you to publish them first — the cluster never receives a chart that is missing queued changes. +
+ +
+ +### Why did my published deployment stay queued for a while? + +Deployments wait for the environment to be consistent before executing: previous deployments finishing, Var Groups settling, Dependencies reaching a final state and the cluster being up. The deployment starts as soon as every gate passes. +
diff --git a/content/docs/en/project/deployment/pending_changes/deployment-detail-pending-changes.png b/content/docs/en/project/deployment/pending_changes/deployment-detail-pending-changes.png new file mode 100644 index 0000000000..4818f4483d Binary files /dev/null and b/content/docs/en/project/deployment/pending_changes/deployment-detail-pending-changes.png differ diff --git a/content/docs/en/project/deployment/pending_changes/pending-publish-badge-projects.png b/content/docs/en/project/deployment/pending_changes/pending-publish-badge-projects.png new file mode 100644 index 0000000000..2e271d7544 Binary files /dev/null and b/content/docs/en/project/deployment/pending_changes/pending-publish-badge-projects.png differ diff --git a/content/docs/en/project/manifests.mdx b/content/docs/en/project/manifests.mdx new file mode 100644 index 0000000000..2ad9ab57ed --- /dev/null +++ b/content/docs/en/project/manifests.mdx @@ -0,0 +1,203 @@ +--- +sidebar_position: 12 +--- +import Zoom from "react-medium-image-zoom"; +import "react-medium-image-zoom/dist/styles.css"; +import { FiExternalLink } from "react-icons/fi"; + +# Manifests + +Every Workload you create in SleakOps is deployed to Kubernetes through a set of **manifests** — the Deployment, Service, Ingress, PodDisruptionBudget and HorizontalPodAutoscaler resources that SleakOps generates for it. The Manifests feature makes those resources first-class citizens: you can inspect each one, customize its YAML, disable it, or add your own extra manifests — per Workload or shared across the whole Project. + +:::info Availability +Manifests are being rolled out progressively. If you don't see the **Advanced** toggle on your Workload forms or the **Manifests** section in your Project's Chart Configuration, the feature is not enabled for your company yet. +::: + +## Where to find them + +Manifests live in two places: + +- **Per Workload** — open any Workload (WebService, Worker, CronJob or Hook) and switch the view toggle from **Form** to **Advanced**. The Advanced view has two tabs: **Manifests** (the graph of resources) and **Values** (see [Values](/docs/project/values)). +- **Per Project** — go to **Project → Settings → Chart Configuration**. The **Manifests** section lists every Workload and manifest in the Project, and manages the shared **project bucket**. + +The **Form** view is still the source of truth for your Workload's configuration: one submit updates every generated manifest. The **Advanced** view is where you inspect and customize what gets deployed. + +## The manifest graph + +The **Manifests** tab shows the Workload's resources as a graph, with the edges representing the relationships between them: + + + Workload Advanced view with the manifest graph + + +Each node shows the manifest's name, its Kind (or resolved host, for Ingress manifests) and its origin: + +| **Origin** | **Badge** | **Meaning** | +| -------------- | ------------ | ----------------------------------------------------------------------------------------------- | +| **Managed** | `Managed` | Generated and kept up to date by SleakOps. Base template updates apply automatically. | +| **Customized** | `Customized` | You edited its YAML. SleakOps never overwrites your copy — see [template updates](#base-template-updates). | +| **Custom** | `Custom` | A manifest you added yourself. It has no SleakOps base template. | + +Disabled manifests show a `Disabled` badge and their edges render dashed. + +You can drag nodes to arrange the graph — positions are saved per Workload, and **Reset layout** restores the automatic arrangement. + +Below the graph, the **Project-shared manifests** strip shows the manifests in the [project bucket](#the-project-bucket) that deploy alongside every Workload, with a **Manage →** shortcut to the Project's Chart Configuration. + +## Editing a manifest + +Click any node to open the manifest editor. The header shows the manifest's kind, origin, base template version, an **Enabled** switch, a copy button and **Delete**. + + + Manifest editor YAML tab with the variables panel + + +The **YAML** tab is where you edit the template. Two kinds of placeholders can appear in it: + +- `<< form >>` variables resolve **before Helm**, from the values of your Workload form (name, namespace, command, healthcheck, etc.). +- `{{ .Values }}` expressions are left for **Helm at deploy time** (replicas, resources, image tag — everything that comes from [Values](/docs/project/values)). + +The **Variables** panel on the right lists everything available: click an entry to insert it at the cursor, or drag it into the editor. + +The editor validates as you type. Errors block saving, and include: + +- Unknown variables not declared in the Workload's variable context. +- Expressions blocked by the template sandbox. +- Removing the protected `sleakops.com/managed` label. +- A `namespace` different from the Project environment (warning — the namespace always belongs to the environment). + +Saving your first structural edit turns a `managed` manifest into `customized`. If the **Deploy?** switch on the graph toolbar is off, the save is registered as a [pending change](/docs/project/deployment/pending_changes); if it's on, a deployment is triggered right away. + +### Preview + +The **Preview** tab renders the template with the current form variables and shows exactly what will be handed to Helm: + + + Manifest editor Preview tab with the rendered template + + +The badges above the output confirm how many `<< form >>` variables were resolved, whether `{{ .Values }}` expressions remain for deploy time, and that the protected invariants are present. If the template fails to render, the errors are listed with their line numbers and a **Fix in YAML** shortcut — a manifest that doesn't render will not deploy. + +## Adding a manifest + +Use **Add manifest** (on the Workload graph toolbar, or in the project bucket) to deploy resources beyond the generated ones: + + + Add manifest modal with scope, kind and template + + +| **Field** | **Description** | +| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------- | +| **Scope** | **This workload** (deploys with the Workload, `<< form >>` variables available) or **Project bucket** (shared, deploys with every release). | +| **Kind** | ConfigMap, Secret, ServiceAccount, NetworkPolicy, PersistentVolumeClaim, CronJob — or **Custom…** for any other kind, including CRDs. | +| **Name** | The manifest's name; it is mirrored into the template's `metadata.name`. | +| **Depends on** | Optional. Draws the graph edges from this manifest to the selected ones. | +| **Template** | The manifest YAML. A starting stub is generated for the selected Kind. | + +Keep in mind: + +- **Cluster-scoped kinds are rejected**, and the `namespace` must equal the Project environment. +- **Custom kinds require their CRD installed in the cluster** — for example, a Keda `ScaledObject` needs the Keda Addon. Otherwise the deploy fails with the corresponding Helm error. + +## The project bucket + +Manifests added with the **Project bucket** scope are not tied to any Workload: they deploy with **every release** of the Project. Typical residents are NetworkPolicies, shared ConfigMaps and ServiceAccounts. Manage them from **Project → Settings → Chart Configuration → Manifests**: + + + Explorer lanes and the shared project bucket + + +The **Explorer** at the top of the section lists every Workload of the Project with its manifests, and the project bucket at the end. Use the filter to search by name or kind; clicking a Workload opens its Advanced view, and clicking a manifest opens the editor in place. + + + Chart Configuration page with the Manifests section + + +:::warning Extends Template & Values is deprecated +The free-form **Extends Template & Values** section below Manifests keeps working, but it is deprecated: new custom resources should be added as manifests. See [Extra Templates](/docs/project/chart/extra_templates). +::: + +## Base template updates + +When you customize a manifest, your copy is pinned: SleakOps **never overwrites it**, even when the base template it came from gets improvements. When a newer base version exists, the editor shows an **update available** badge and a banner with a **View diff** button: + +- Green lines are what the new base adds. +- Red lines are your customizations, absent from the base. + +From the diff you can choose **Keep my version** or **Reset to v<new>**. **Reset to base** (also available in the editor header) discards your structural edits, restores the SleakOps base template and turns the manifest back into `managed`. Form values are not affected — they only fill variables. + +## Disabling and deleting + +- **Disable** (the Enabled switch): the manifest is skipped on the next deploy but keeps its configuration. If the resource was already deployed, the next deploy removes it from the cluster. +- **Delete**: the manifest will no longer be deployed, and SleakOps will **not re-create it** on future seeds or base-template updates. You can add an equivalent manifest back later. + +## Deploying your changes + +Every content change in the Manifests view respects the **Deploy?** switch on the toolbar: + +- **On** — a deployment is triggered right after each save. +- **Off** — changes accumulate as [pending changes](/docs/project/deployment/pending_changes) and are deployed when you publish them. + +Layout-only actions — dragging nodes or **Reset layout** — are cosmetic: they never create a pending change or a deployment, regardless of the switch. + +## FAQs + +
+ +### Can I modify the templates SleakOps generates? + +Yes. Open the Workload's Advanced view, click the manifest and edit its YAML. Your copy becomes customized and is never overwritten by SleakOps. +
+ +
+ +### What happens to my existing Extra Templates? + +They keep deploying exactly as before. The Extends Template & Values section is deprecated in favor of Manifests, so migrate custom resources to manifests as you touch them — one manifest per resource, with validation and preview instead of one free-form blob. +
+ +
+ +### Can I deploy resources from a CRD? + +Yes — choose **Custom…** as the Kind when adding a manifest and set the CRD's apiVersion/kind. The CRD must be installed in the cluster (for example, Keda's ScaledObject requires the Keda Addon), otherwise the deploy fails with the corresponding Helm error. +
+ +
+ +### Why can't I change the namespace of a manifest? + +Each Project environment deploys into its own Kubernetes Namespace. Manifests always deploy to the environment's namespace — a different value is rejected to keep environments isolated. +
+ +
+ +### What's the difference between disabling and deleting a manifest? + +Disabling keeps the manifest and its configuration but skips it at deploy time — flip the switch back to re-include it. Deleting removes it for good: SleakOps won't re-create it on future updates, though you can always add a new manifest with the same content. +
+ +
+ +### Who can edit manifests? + +Editing follows your platform role: viewers see the graph, the YAML and the previews in read-only mode; editors and admins can customize, add, disable and delete manifests. +
diff --git a/content/docs/en/project/manifests/add-manifest-modal.png b/content/docs/en/project/manifests/add-manifest-modal.png new file mode 100644 index 0000000000..2d30d3f389 Binary files /dev/null and b/content/docs/en/project/manifests/add-manifest-modal.png differ diff --git a/content/docs/en/project/manifests/manifest-editor-preview.png b/content/docs/en/project/manifests/manifest-editor-preview.png new file mode 100644 index 0000000000..d6ae62c621 Binary files /dev/null and b/content/docs/en/project/manifests/manifest-editor-preview.png differ diff --git a/content/docs/en/project/manifests/manifest-editor-yaml.png b/content/docs/en/project/manifests/manifest-editor-yaml.png new file mode 100644 index 0000000000..e99029baa5 Binary files /dev/null and b/content/docs/en/project/manifests/manifest-editor-yaml.png differ diff --git a/content/docs/en/project/manifests/project-manifests-explorer.png b/content/docs/en/project/manifests/project-manifests-explorer.png new file mode 100644 index 0000000000..01662836a0 Binary files /dev/null and b/content/docs/en/project/manifests/project-manifests-explorer.png differ diff --git a/content/docs/en/project/manifests/project-shared-bucket.png b/content/docs/en/project/manifests/project-shared-bucket.png new file mode 100644 index 0000000000..769e61bce2 Binary files /dev/null and b/content/docs/en/project/manifests/project-shared-bucket.png differ diff --git a/content/docs/en/project/manifests/workload-advanced-manifests.png b/content/docs/en/project/manifests/workload-advanced-manifests.png new file mode 100644 index 0000000000..48e47357d1 Binary files /dev/null and b/content/docs/en/project/manifests/workload-advanced-manifests.png differ diff --git a/content/docs/en/project/values.mdx b/content/docs/en/project/values.mdx new file mode 100644 index 0000000000..a2f0ae0ca3 --- /dev/null +++ b/content/docs/en/project/values.mdx @@ -0,0 +1,112 @@ +--- +sidebar_position: 13 +--- +import Zoom from "react-medium-image-zoom"; +import "react-medium-image-zoom/dist/styles.css"; +import { FiExternalLink } from "react-icons/fi"; + +# Values + +Every deployment renders your Project's Helm chart with a **values tree**: replicas, resources, image tags, hosts, probes and everything else that parameterizes the [manifests](/docs/project/manifests). SleakOps generates those values for you, and lets you override them at three persistent levels — plus a fourth, ephemeral level at deploy time. + +## The override levels + +Values are deep-merged level by level at deploy time. Each level overrides the one before it — the most specific scope wins: + +| **Level** | **Scope** | **Where you set it** | +| --------- | ------------------------------- | ---------------------------------------------------------------------------------- | +| **1** | Generated by SleakOps | Nowhere — derived from your Workload forms, Dependencies and Var Groups (read-only). | +| **2** | Project global | **Project → Settings → Chart Configuration**, the **Values** editor. | +| **3** | Workload override | The Workload's **Advanced → Values** tab (**Workload override** editor). | +| **4** | Deploy-time values (ephemeral) | The [CLI](/docs/cli#injecting-values-on-deploy): `sleakops deploy -f values.yaml` or `--set key.path=value`. | + +Levels 2 and 3 are persistent: they apply to every subsequent deployment until you change them. Level 4 applies to **one deployment only**. + +:::info List merging +Unlike plain Helm, the level merge **combines lists** instead of replacing them — an override that redefines a list adds to the generated entries rather than dropping them. +::: + +## The Workload Values tab + +Open a Workload, switch to **Advanced** and select the **Values** tab: + + + Workload Values tab with the generated values and the workload override + + +- **Generated by SleakOps** (read-only) — the values SleakOps derived for this Workload from its form: command, probes, resources, node selector, hosts, and so on. +- **Workload override** — a YAML mapping merged **over** the generated values, for this Workload only. Save it with **Save override**. + +For Ingress values, each key under `hosts:` represents one domain. To tune a single host, override a key inside that entry — for example `hosts..custom_service` — instead of redefining the whole block. + +### Effective values + +The **Effective values — what Helm receives** table at the bottom answers "what will actually deploy": one row per overridden key, with the value each level contributes and a badge naming the winning source. + + + Effective values table showing generated, project and workload columns + + +In the example above, `resources.limits.memory` is generated as `1331Mi`, raised to `1536Mi` by a project global, and finally set to `2048Mi` by the workload override — the workload has the last word. + +## Project global values + +Project-wide overrides live in **Project → Settings → Chart Configuration**, in the **Values** editor of the Extends Template & Values section. The deprecation notice shown on that section is about migrating free-form **templates** to [Manifests](/docs/project/manifests) — the Values editor remains the home of project globals. Nest the keys under the Workload's name (or under `global:` for chart-wide values): + + + Project global values editor in Chart Configuration + + +```yaml +backoffice: + resources: + limits: + memory: 1536Mi +``` + +Use project globals for values you want every Workload of the Project to inherit consistently; use workload overrides for the exceptions. + +## Deploy-time values (CLI) + +For values that belong to a single deployment — a canary replica bump, a one-off feature flag — inject them from your pipeline with `sleakops deploy -f values.yaml`, `--set key=value` or `--set-string key=value`. They win over every persistent level, apply to that deployment only, and the next deploy without them reverts to the platform values. + +See [Injecting values on deploy](/docs/cli#injecting-values-on-deploy) for the full syntax and caveats. + +## FAQs + +
+ +### Which value wins if the same key is set at several levels? + +The most specific one: deploy-time values beat the workload override, which beats the project global, which beats the generated value. The Effective values table shows the winner per key with its source badge. +
+ +
+ +### Does saving an override trigger a deployment? + +Saving a workload override registers a pending change — you deploy it when you publish. In the project's Chart Configuration, the Deploy? switch decides: on triggers a deployment on Apply changes, off leaves the update as a pending change. +
+ +
+ +### How do I see the values a Workload will actually receive? + +The Effective values table in the Workload's Values tab shows the merged result per key. The manifest Preview tab shows where each {{ .Values }} expression lands in the rendered template. +
+ +
+ +### Should I put secrets in values? + +No. Secrets belong in Var Groups, which are stored encrypted and injected as Kubernetes Secrets. Values are chart configuration, not a secrets store — and deploy-time --set/--set-string flags additionally end up in your shell history. +
diff --git a/content/docs/en/project/values/project-global-values.png b/content/docs/en/project/values/project-global-values.png new file mode 100644 index 0000000000..96f32780cb Binary files /dev/null and b/content/docs/en/project/values/project-global-values.png differ diff --git a/content/docs/en/project/values/workload-effective-values.png b/content/docs/en/project/values/workload-effective-values.png new file mode 100644 index 0000000000..ddde944712 Binary files /dev/null and b/content/docs/en/project/values/workload-effective-values.png differ diff --git a/content/docs/en/project/values/workload-values-tab.png b/content/docs/en/project/values/workload-values-tab.png new file mode 100644 index 0000000000..cd70da8ecf Binary files /dev/null and b/content/docs/en/project/values/workload-values-tab.png differ diff --git a/content/docs/en/responsability-model.mdx b/content/docs/en/responsability-model.mdx index 1b6af881b8..756a89ca3f 100644 --- a/content/docs/en/responsability-model.mdx +++ b/content/docs/en/responsability-model.mdx @@ -9,4 +9,6 @@ We transparently utilize all AWS services, which means the responsibility extend To safeguard your data and ensure it doesn't get lost due to potential service disruptions, it's advisable to have backup policies in place. Currently, we don't support backups for our dependencies (RDS, S3, RabbitMQ, etc.). To set this up, you can access via your AWS client and define your backup policies. [Learn more about AWS's Shared Responsibility Model] -(https://aws.amazon.com/compliance/shared-responsibility-model/) \ No newline at end of file +(https://aws.amazon.com/compliance/shared-responsibility-model/) + +For what's covered by SleakOps support specifically, see [Support](/docs/support). \ No newline at end of file diff --git a/content/docs/en/support.mdx b/content/docs/en/support.mdx new file mode 100644 index 0000000000..e1fa7679dd --- /dev/null +++ b/content/docs/en/support.mdx @@ -0,0 +1,37 @@ +--- +sidebar_position: 18 +--- + +# Support + +If you run into an issue or have a question, the fastest way to get help is through **Support**, in the main sidebar of the console — it combines an AI-powered chat with support tickets for your account. Before reaching out, it's worth a quick search here in the docs: most day-to-day questions are already answered in a tutorial or FAQ. + +## What our support covers + +- Errors in the SleakOps platform itself. +- Errors in infrastructure resources automatically managed by SleakOps (clusters, environments, dependencies, addons). +- Help updating resources provisioned with SleakOps. +- Infrastructure state locks (resources stuck in a state). +- Support finding workarounds for customizations the platform doesn't cover. + +## Where to look first + +For a few common questions, the fastest answer is one you can get yourself, right now: + +- **Something's wrong in your application or its code** — that's owned and debugged by your own team; SleakOps manages the infrastructure your application runs on, not the application itself. As a first step, you can run an AI-powered [Autodiagnostic](/docs/powered-ai/autodiagnostic) on the workload to guide the investigation. +- **The application feels slow** — start with [Grafana](/docs/cluster/addons/grafana) to see what your workloads are actually using, before assuming it's an infrastructure problem. +- **Questions about your Dockerfile or build configuration** — see [Configure your Dockerfile](/docs/project/configure_your_dockerfile) for what's supported out of the box. +- **You want to understand or reduce your AWS spend** — see the [Cost Review Guide](/tutorial/cost-review-guide) to read what you're already spending, and [AWS Cost Optimization Strategies](/tutorial/optimize-aws-costs) for concrete ways to bring it down. +- **Choosing AWS services or designing your architecture** — see the [Responsibility Model](/docs/responsability-model) below and [AWS's own documentation](https://docs.aws.amazon.com/) for guidance; these decisions are yours to make for your application. + +## Responsibility at a glance + +| | SleakOps | You | +|---|---|---| +| **Platform & infrastructure** | Clusters, networking, provisioning, and the resources SleakOps creates for you — as long as you don't modify them directly in AWS, outside the platform. | Configure environment variables, define resource requirements, and monitor usage | +| **Your application** | Provide runtime environment, CI/CD pipelines capabilities, and observability tools (logs/metrics) | Your code, its dependencies, and its performance | +| **Data & backups** | Expose the resource's backup settings in the dependency form (e.g. the RDS "Automated Backup" toggle and retention period) | Define and manage backup and restoration policies for your dependencies — RDS, S3, RabbitMQ — and their secure storage (see [Responsibility Model](/docs/responsability-model)) | + +## Still not sure? + +If you're not sure whether something is covered, just ask — reach out through **Support** and we'll point you in the right direction. diff --git a/content/docs/es/cli.mdx b/content/docs/es/cli.mdx index cb6a60ed16..d230f2d68c 100644 --- a/content/docs/es/cli.mdx +++ b/content/docs/es/cli.mdx @@ -65,15 +65,15 @@ sleakops build -p myproject -b main --docker-args "ARG1=value1,ARG2=value2" Esto es particularmente útil para pipelines de CI/CD donde quieres pasar diferentes argumentos basados en el entorno o contexto de construcción. ::: -Cuando usas **wait**, también puedes definir un **timeout** (en minutos) para limitar cuánto espera la CLI a que termine la compilación. El valor por defecto es **180 minutos**; pasa `0` para esperar indefinidamente. También puedes configurarlo mediante la variable de entorno `BUILD_TIMEOUT_MINUTES`. +Puedes definir un **timeout** (en minutos) para un build. Este es el tiempo de vida máximo del build en el backend: si el build tarda más, SleakOps lo detiene y lo marca como fallido, de modo que un build colgado no se queda corriendo para siempre. El valor por defecto es **180 minutos**, y todo build queda acotado aunque no lo pases. Cuando además usas **wait**, `--timeout` también limita cuánto observa la CLI al build. El valor por defecto de la CLI se puede configurar mediante la variable de entorno `BUILD_TIMEOUT_MINUTES`. | **Opción** | **Descripción** | | ------------- | ------------------------------------------------------------------------------------- | | **--wait** | Espera a que la compilación termine antes de retornar. | -| **--timeout** | Minutos a esperar cuando se usa `--wait`. Por defecto `180`. Usa `0` para sin límite. | +| **--timeout** | Tiempo de vida máximo del build en minutos; también limita cuánto observa la CLI con `--wait`. Por defecto `180`. `0` mantiene el valor por defecto de la plataforma y deja que `--wait` observe indefinidamente. | :::tip -El timeout es del lado del cliente: controla cuánto observa la CLI a la compilación, no la compilación en sí en el backend. Cuando se agota, la CLI imprime un mensaje y sale con código `1`, de modo que una compilación colgada hace fallar tu pipeline de CI en vez de pasar silenciosamente. +`--timeout` funciona en dos niveles: el backend detiene el build cuando supera el límite (esto ocurre para todo build, incluso sin `--wait`), y — cuando pasás `--wait` — la CLI también deja de observar pasado ese tiempo y sale con código `1`, de modo que un build colgado hace fallar tu pipeline de CI en vez de quedarse colgado. ::: ### 3. Realizar un Despliegue @@ -88,6 +88,31 @@ SleakOps gestiona de manera transparente el proceso de despliegue, asegurando qu Aquí, **project** y **environment** son los argumentos obligatorios. El usuario puede añadir una **build** o **tag** de imagen para especificar una imagen. Aquí también están presentes las opciones de **wait** y **key**, su uso es el mismo que en el comando de compilación. +### Inyectar values en el deploy + +Puedes inyectar values de Helm en un deployment puntual, por encima de todo lo configurado en la plataforma (ver [Values](/docs/project/values) para los niveles de override): + +```plain +sleakops deploy -p myapp -e prod -f values.prod.yaml +sleakops deploy -p myapp -e prod --set api_web.replicas=3 +cat values.yaml | sleakops deploy -p myapp -e prod -f - +``` + +| **Opción** | **Descripción** | +| ---------------- | -------------------------------------------------------------------------------------------------------------- | +| **-f, --values** | Archivo YAML con values para este deploy (repetible; `-` lee stdin; el último archivo gana). | +| **--set** | Define un valor puntual, `clave.ruta=valor` (repetible; gana sobre `-f`). Aplica coerción YAML: `5` → int, `true` → bool. | +| **--set-string** | Como `--set` pero el valor se mantiene siempre como string (sin coerción). | + +:::warning Efímeros por diseño +Los values por deploy aplican a **ese deployment solamente** — ganan sobre todos los values configurados en la plataforma, y el próximo deploy sin `-f`/`--set`/`--set-string` vuelve a los valores de la plataforma. Son la herramienta para ajustes puntuales, no para configuración durable: los cambios durables van a nivel Project o Workload. +::: + +Dos consideraciones: + +- **Para secretos prefiere `-f`** (o stdin): los argumentos de `--set` y `--set-string` quedan en el historial de tu shell y en los logs del CI. +- **Dos semánticas de listas distintas**: entre tus propios inputs (archivos `-f` y flags `--set`) una lista reemplaza a la anterior, exactamente como Helm. Pero cuando tus values del deploy se mergean contra los niveles de la plataforma, las listas se **combinan** en lugar de reemplazarse — una entrada que pasás se suma a las generadas, no las descarta. + ## Ejemplos de CI/CD Con la CLI de SleakOps, puedes integrar tus tuberías de CI/CD, automatizar el proceso de compilación y despliegue, y concentrarte en entregar aplicaciones excepcionales sin la molestia de intervención manual. diff --git a/content/docs/es/domain/delegation.mdx b/content/docs/es/domain/delegation.mdx index 4d5753cffe..747b1fbf86 100644 --- a/content/docs/es/domain/delegation.mdx +++ b/content/docs/es/domain/delegation.mdx @@ -69,7 +69,9 @@ ns-012.awsdns-01.co.uk ### Registradores Comunes
-GoDaddy + +GoDaddy + 1. Ve a [Administrador de Dominios](https://account.godaddy.com/products) 2. Haz clic en tu dominio @@ -81,7 +83,9 @@ ns-012.awsdns-01.co.uk
-Namecheap + +Namecheap + 1. Ve a [Lista de Dominios](https://ap.www.namecheap.com/domains/list/) 2. Haz clic en "Administrar" junto a tu dominio @@ -92,7 +96,9 @@ ns-012.awsdns-01.co.uk
-Cloudflare + +Cloudflare + **Nota:** Si usas Cloudflare, debes deshabilitar el proxy de Cloudflare para una delegación adecuada. diff --git a/content/docs/es/project/build/build.mdx b/content/docs/es/project/build/build.mdx index 5d3131fd68..b84ee97377 100644 --- a/content/docs/es/project/build/build.mdx +++ b/content/docs/es/project/build/build.mdx @@ -6,32 +6,60 @@ import { FiExternalLink } from "react-icons/fi"; # Build -We have repeteadly talked about Build in both [Project documentation ](/docs/project) and [Initial Build documentation](/docs/project). A build is basically a template of an OS, libraries and other dependencies of the project you deploy. +Ya hablamos del Build tanto en la [documentación de Proyecto](/docs/project) como en la [documentación del Build inicial](/docs/project). Un build es, básicamente, una plantilla del sistema operativo, las librerías y demás dependencias del proyecto que vas a desplegar. -### Build creation +### Creación de un Build -To create a Build you only need four parameters, only the Project field is required as the other three are, if not set, wait until this access is automatically enabled are chosen by default: -- Project: Refers to what we call ProjectEnv, here you choose which ProjectEnv you want to build. -- Branch: Lets you choose any branch of the repository that you've chosen as Project. Defaults to Environment name. -- Commit hash: You can also choose the commit has to build a specific commit and not the last one as we do by default. Defaults to last commit. -- Tag: Just a tag to differentiate builds. Defaults to 'latest'. +Para crear un Build solo el campo Project es obligatorio; los otros tres son opcionales y toman un valor por defecto si no los completás: +- Project: hace referencia a lo que llamamos ProjectEnv; acá elegís qué ProjectEnv querés buildear. +- Branch: te permite elegir cualquier branch del repositorio que hayas elegido como Project. Por defecto, el nombre del Environment. +- Commit hash: también podés elegir el commit para buildear un commit específico en lugar del último, que es lo que hacemos por defecto. Por defecto, el último commit. +- Tag: simplemente un tag para diferenciar builds. Por defecto, 'latest'. -## Why do we need to Build a Docker image? +## ¿Por qué necesitamos buildear una imagen de Docker? -As we use [Helm charts ](https://helm.sh/docs/) we need the image because is what they use to deploy a Kubernetes Release. +Como usamos [Helm charts ](https://helm.sh/docs/), necesitamos la imagen porque es lo que usan para desplegar un Release de Kubernetes. :::info -Remember that you need a Build to update the code that the Deployment runs inside the Kubernetes Cluster. +Recordá que necesitás un Build para actualizar el código que el Deployment ejecuta dentro del Cluster de Kubernetes. ::: -:::tip CI/CD integration with SleakOps +:::tip Integración CI/CD con SleakOps -SleakOps has its own CLI Tool that you can use to automate Builds and Deployments in your CI/CD. More info [here](/docs/cli). +SleakOps tiene su propia herramienta de CLI que podés usar para automatizar Builds y Deployments en tu CI/CD. Más info [acá](/docs/cli). ::: -## FAQs +## Tiempo límite de build (timeout) + +Cada build se ejecuta con un tiempo de vida máximo. Si un build se queda trabado — esperando un lock, descargando una imagen que nunca llega, o repitiéndose dentro de un paso del build — SleakOps lo detiene automáticamente y lo marca como fallido, en lugar de dejarlo correr indefinidamente. Si no definís un límite, se aplica un valor por defecto de 180 minutos, de modo que todo build siempre tiene un tope. + +Definí el límite por build desde la [CLI de SleakOps](/docs/cli) con la opción `--timeout`, en minutos: + +```bash +sleakops build --project my-app --branch main --timeout 30 +``` + +| **Valor de `--timeout`** | **Efecto** | +| ------------------------ | --------------------------------------------------------------------------------------------- | +| **Omitido** | Se aplica el valor por defecto de 180 minutos. | +| **Un número positivo** | El build se detiene y se marca como fallido luego de esa cantidad de minutos. | +| **`0`** | El build igual queda acotado por el valor por defecto de la plataforma. Con `--wait`, además quita el límite de espera de la CLI, que entonces espera hasta que el build termine; sin `--wait` se comporta como omitir `--timeout`. | + +Combinado con `--wait`, `--timeout` también limita cuánto espera la CLI a que el build termine antes de salir con error. Esto es útil en pipelines de CI/CD, donde un build trabado bloquearía el job indefinidamente: + +```bash +sleakops build --project my-app --branch main --wait --timeout 30 +``` + +Si el build no termina dentro del timeout, la CLI sale con un código distinto de cero para que el paso del pipeline falle rápido. + +:::tip +Para CI/CD, configurá `--timeout` con un valor un poco mayor a la duración normal de tu build. Así un build realmente trabado se detecta rápido, mientras que los builds sanos siempre tienen margen para terminar. +::: + +## Preguntas frecuentes
diff --git a/content/docs/es/project/chart/extra_templates.mdx b/content/docs/es/project/chart/extra_templates.mdx index 4c51291716..439ed29066 100644 --- a/content/docs/es/project/chart/extra_templates.mdx +++ b/content/docs/es/project/chart/extra_templates.mdx @@ -7,6 +7,10 @@ import { FiExternalLink } from "react-icons/fi"; # Extra Templates +:::warning Deprecado en favor de Manifests +Extender templates y values está deprecado. Para agregar o editar recursos personalizados, usa la sección **Manifests** del Project — cada recurso se vuelve su propio manifiesto, con validación, preview y scoping por Workload. Ver la [documentación de Manifests](/docs/project/manifests). Los Extra Templates existentes se siguen desplegando como siempre hasta que los migres. +::: + Los Extra Templates te permiten desplegar recursos personalizados de Kubernetes más allá de los componentes integrados de SleakOps. Esta poderosa funcionalidad te permite extender tu proyecto con recursos especializados como Ingresses personalizados, pods de prueba, u otros objetos de Kubernetes adaptados a tus requisitos específicos. ## Casos de Uso diff --git a/content/docs/es/project/chart/index.mdx b/content/docs/es/project/chart/index.mdx index 2ed71a1fcb..f201bce044 100644 --- a/content/docs/es/project/chart/index.mdx +++ b/content/docs/es/project/chart/index.mdx @@ -69,33 +69,40 @@ Valores que se aplican a todo el Proyecto: ## Preguntas Frecuentes
- ### ¿Dónde puedo encontrar el Chart de mi Proyecto? + + ### ¿Dónde puedo encontrar el Chart de mi Proyecto? + Actualmente, los Charts no son visibles directamente en la plataforma. Sin embargo, puedes descargar el Chart desde el repositorio ECR creado para tu Proyecto en la Cuenta AWS correspondiente.
- ### ¿Puedo modificar el Chart desplegado por un Proyecto? - Sí, con algunas limitaciones. Puedes: - Agregar plantillas personalizadas - usando [**Extra Templates**](/docs/project/chart/extra_templates) - Agregar dependencias de - chart usando [**Chart Dependencies**](/docs/project/chart/chart_dependencies), similar a - [Helm Chart Dependencies - ](https://helm.sh/docs/helm/helm_dependency/) + + ### ¿Puedo modificar el Chart desplegado por un Proyecto? + + Sí. Puedes: + + - Personalizar o agregar [**Manifests**](/docs/project/manifests) por Workload o compartidos en el Project + - Sobreescribir [**Values**](/docs/project/values) a nivel Project o Workload + - Agregar dependencias de chart usando [**Chart Dependencies**](/docs/project/chart/chart_dependencies), similar a [Helm Chart Dependencies ](https://helm.sh/docs/helm/helm_dependency/)
- ### ¿Puedo agregar un Ingress personalizado a mi Proyecto? - Sí, este es uno de los casos de uso principales de la funcionalidad **Extra - Templates**. Consulta la [documentación de Extra - Templates](/docs/project/chart/extra_templates) para instrucciones detalladas. + + ### ¿Puedo agregar un Ingress personalizado a mi Proyecto? + + Sí — agrégalo como manifiesto desde la vista Advanced del Workload o desde el + project bucket. Ver la [documentación de Manifests](/docs/project/manifests). + El camino legacy de [Extra Templates](/docs/project/chart/extra_templates) + sigue funcionando pero está deprecado.
### ¿Puedo modificar las plantillas existentes de Kubernetes Service? - No, la modificación de plantillas integradas de SleakOps no está soportada - actualmente. Estamos trabajando en habilitar modificaciones a las plantillas - integradas en futuras versiones. + Sí. Abre la vista **Advanced** del Workload, haz clic en el manifiesto y edita + su YAML — tu copia se conserva y SleakOps nunca la sobreescribe. Ver + [Manifests](/docs/project/manifests).
diff --git a/content/docs/es/project/dependency/index.mdx b/content/docs/es/project/dependency/index.mdx index 3783b5588c..9b93d4f239 100644 --- a/content/docs/es/project/dependency/index.mdx +++ b/content/docs/es/project/dependency/index.mdx @@ -134,6 +134,10 @@ Para dependencias de base de datos (MySQL, PostgreSQL, etc.): - **Cadenas de Conexión**: Generadas automáticamente y almacenadas como secrets de Kubernetes - **Autenticación**: Gestionada a través de roles IAM y credenciales específicas de la base de datos - **SSL/TLS**: Las conexiones encriptadas se configuran por defecto +- **Encriptación at-rest**: Habilitada por defecto en dependencias nuevas + - Podés desactivarla o configurar tu propia KMS key al crearla + - Aurora (PostgreSQL/MySQL) siempre está encriptada, sin opción de desactivarlo + - Si la dependencia ya existía antes de esta mejora, verificá el caso puntual: puede no estar encriptada - **Connection Pooling**: Gestión optimizada de conexiones para mejor rendimiento #### Acceso a Cache @@ -170,4 +174,4 @@ Si encuentras problemas de acceso con dependencias: 2. Confirma que tu carga de trabajo tiene la service account correcta 3. Revisa los permisos del rol IAM para la dependencia 4. Verifica la conectividad de red y configuraciones de security groups -::: \ No newline at end of file +::: diff --git a/content/docs/es/project/dependency/oracle-aws.mdx b/content/docs/es/project/dependency/oracle-aws.mdx index 42b9ed363c..613bafd523 100644 --- a/content/docs/es/project/dependency/oracle-aws.mdx +++ b/content/docs/es/project/dependency/oracle-aws.mdx @@ -12,14 +12,18 @@ SleakOps facilita la integración de bases de datos Oracle a través de Amazon R ## Preguntas Frecuentes
- ### Licencia + + ### Licencia + Al crear una base de datos Oracle en Sleakops se utiliza License Included (LI). Actualmente no se admite Bring Your Own License (BYOL); sin embargo, contacta al soporte para más información.
- ### ¿Cómo gestiona SleakOps las credenciales de Oracle? + + ### ¿Cómo gestiona SleakOps las credenciales de Oracle? + Cuando creas una dependencia de Oracle en SleakOps, se genera automáticamente un Vargroup para tu base de datos. Este Grupo de Variables almacena de forma segura las credenciales de Oracle y otros detalles importantes de @@ -29,7 +33,9 @@ SleakOps facilita la integración de bases de datos Oracle a través de Amazon R
- ### ¿Qué es el despliegue Multi-AZ y debería habilitarlo? + + ### ¿Qué es el despliegue Multi-AZ y debería habilitarlo? + El despliegue Multi-AZ (Zona de Disponibilidad múltiple) garantiza alta disponibilidad y soporte de failover replicando tu base de datos en otra zona de disponibilidad. Se recomienda para entornos de producción para evitar diff --git a/content/docs/es/project/deployment/index.mdx b/content/docs/es/project/deployment/index.mdx index 8b48bcc66e..ab8ca7d763 100644 --- a/content/docs/es/project/deployment/index.mdx +++ b/content/docs/es/project/deployment/index.mdx @@ -13,7 +13,7 @@ Un **Deployment** en SleakOps significa la instalación de una nueva versión de :::info -Cuando haya una actualización de cualquiera de estos recursos, SleakOps te notificará acerca de un Deployment a través del banner de no publicado mostrado [abajo](#unpublished-banner). +Cuando haya una actualización de cualquiera de estos recursos que no se desplegó inmediatamente, SleakOps la encola como un [cambio pendiente](/docs/project/deployment/pending_changes) y muestra un badge **Publish** en el entorno. ::: @@ -41,12 +41,9 @@ Si no realizas el deployment de tus cambios inmediatamente, o si tu modificació -#### Unpublished banner +#### Cambios pendientes -- **Unpublished Changes Banner**: Este banner se muestra cuando hay contenido pendiente que aún no se ha desplegado en el clúster. A través de este banner, puedes elegir desplegar solo los VariableGroups o si deseas desplegar todo, incluidos los Workloads en estado 'borrador'. - - DEPLOY-deploy-changes-banner - +- **Badge Publish**: los entornos con contenido pendiente que aún no se desplegó en el clúster muestran un badge **Publish** en la lista de Projects, el dashboard del Project y la lista de Deployments. Hacer clic en él abre el detalle del deployment pendiente, donde revisas los cambios acumulados y los publicas. Ver [Cambios Pendientes y Publicación](/docs/project/deployment/pending_changes). - A través del [CLI ](/docs/cli). \ No newline at end of file diff --git a/content/docs/es/project/deployment/pending_changes.mdx b/content/docs/es/project/deployment/pending_changes.mdx new file mode 100644 index 0000000000..187ca22276 --- /dev/null +++ b/content/docs/es/project/deployment/pending_changes.mdx @@ -0,0 +1,83 @@ +--- +sidebar_position: 3 +--- +import Zoom from "react-medium-image-zoom"; +import "react-medium-image-zoom/dist/styles.css"; + +# Cambios Pendientes y Publicación + +No todos los cambios tienen que llegar al cluster inmediatamente. Cada vez que guardas una edición con el switch **Deploy?** apagado — una edición de Workload, una personalización de [manifiestos](/docs/project/manifests), un override de [values](/docs/project/values), una actualización de Var Group — SleakOps la registra como un **cambio pendiente** en lugar de desplegarla. Los cambios pendientes se acumulan por entorno hasta que los revisas y publicas con un clic. + +## Cómo se acumulan los cambios + +Cada entorno del Project mantiene **como máximo un Release pendiente y un Deployment pendiente**: + +- Los cambios que afectan al chart — Workloads, manifiestos, chart dependencies — crean o actualizan el **Release** pendiente, recalculando su versión y sumando una línea a la lista de cambios, con un **Deployment** pendiente apuntándole. +- Los cambios de Var Groups solo encolan el **Deployment** pendiente: actualizan values, así que se reusa el Release actual del entorno en lugar de cortar una versión nueva del chart. +- Las versiones siguen el semver del chart: crear o borrar un Workload sube el *minor*; las ediciones de Workloads, manifiestos o chart dependencies suben el *patch*. +- La publicación es siempre manual — SleakOps nunca aprueba cambios pendientes automáticamente. +- Si alguien dispara un deployment directo en el medio, este **reemplaza** al pendiente: el Release y el Deployment pendientes se descartan, así el entorno nunca arrastra cambios encolados viejos. + +## El badge Publish + +Los entornos con cambios pendientes muestran un badge rosa **Publish**: + + + Lista de Projects con el badge Publish en un entorno con cambios pendientes + + +El badge aparece en tres lugares: + +- La lista de **Projects**, en cada fila de entorno con cambios pendientes. +- El header del **dashboard del Project**. +- La lista de **Deployments**, en el deployment cuyo estado es `Pending Approval`. + +## Revisar y publicar + +Hacer clic en el badge abre el detalle del deployment pendiente. La sección **Pending Changes** lista todos los cambios acumulados, junto con la versión del Release pendiente y hace cuánto empezó la cola: + + + Detalle del deployment con la sección Pending Changes y el botón Publish + + +Presiona **Publish** para lanzarlo. SleakOps publica el Release pendiente del chart (cuando lo hay) y encadena el deployment a continuación — puedes seguir su progreso en la sección de [Deployments](/docs/project/deployment). Los badges desaparecen apenas el deployment sale del estado `Pending Approval`. + +:::info Permisos +Los viewers pueden abrir el detalle y leer los cambios pendientes, pero solo los editors y admins pueden publicar. El botón Publish también se oculta cuando navegas una cuenta en modo solo lectura. +::: + +## FAQs + +
+ +### ¿Qué crea un cambio pendiente? + +Cualquier edición guardada con el switch Deploy? apagado: alta/edición/baja de Workloads, personalizaciones y altas de manifiestos, overrides de values, cambios de Var Groups y actualizaciones de chart dependencies. Las ediciones guardadas con el switch prendido se despliegan al instante. +
+ +
+ +### ¿Puedo descartar los cambios pendientes? + +No hay un descarte explícito. Disparar un deployment directo (por ejemplo desde un Build, o vía el CLI) reemplaza el Release y el Deployment pendientes con el estado actual del entorno. +
+ +
+ +### ¿Qué pasa si aparecen cambios nuevos después de publicar? + +Los cambios publicables hechos entre la publicación y el deploy real cancelan el deployment con un mensaje pidiendo publicarlos primero — el cluster nunca recibe un chart al que le falten cambios encolados. +
+ +
+ +### ¿Por qué mi deployment publicado quedó encolado un rato? + +Los deployments esperan a que el entorno esté consistente antes de ejecutarse: que terminen los deployments anteriores, que los Var Groups se asienten, que las Dependencies lleguen a un estado final y que el cluster esté prendido. El deployment arranca apenas pasan todas las compuertas. +
diff --git a/content/docs/es/project/deployment/pending_changes/deployment-detail-pending-changes.png b/content/docs/es/project/deployment/pending_changes/deployment-detail-pending-changes.png new file mode 100644 index 0000000000..4818f4483d Binary files /dev/null and b/content/docs/es/project/deployment/pending_changes/deployment-detail-pending-changes.png differ diff --git a/content/docs/es/project/deployment/pending_changes/pending-publish-badge-projects.png b/content/docs/es/project/deployment/pending_changes/pending-publish-badge-projects.png new file mode 100644 index 0000000000..2e271d7544 Binary files /dev/null and b/content/docs/es/project/deployment/pending_changes/pending-publish-badge-projects.png differ diff --git a/content/docs/es/project/manifests.mdx b/content/docs/es/project/manifests.mdx new file mode 100644 index 0000000000..5537505172 --- /dev/null +++ b/content/docs/es/project/manifests.mdx @@ -0,0 +1,203 @@ +--- +sidebar_position: 12 +--- +import Zoom from "react-medium-image-zoom"; +import "react-medium-image-zoom/dist/styles.css"; +import { FiExternalLink } from "react-icons/fi"; + +# Manifests + +Cada Workload que creas en SleakOps se despliega en Kubernetes a través de un conjunto de **manifiestos** — los recursos Deployment, Service, Ingress, PodDisruptionBudget y HorizontalPodAutoscaler que SleakOps genera para él. La funcionalidad de Manifests convierte esos recursos en ciudadanos de primera clase: puedes inspeccionar cada uno, personalizar su YAML, deshabilitarlo o agregar tus propios manifiestos extra — por Workload o compartidos a nivel del Project. + +:::info Disponibilidad +Manifests se está habilitando progresivamente. Si no ves el toggle **Advanced** en los formularios de tus Workloads ni la sección **Manifests** en la Chart Configuration de tu Project, la funcionalidad todavía no está habilitada para tu compañía. +::: + +## Dónde encontrarlos + +Los manifiestos viven en dos lugares: + +- **Por Workload** — abre cualquier Workload (WebService, Worker, CronJob o Hook) y cambia el toggle de vista de **Form** a **Advanced**. La vista Advanced tiene dos tabs: **Manifests** (el grafo de recursos) y **Values** (ver [Values](/docs/project/values)). +- **Por Project** — ve a **Project → Settings → Chart Configuration**. La sección **Manifests** lista todos los Workloads y manifiestos del Project, y administra el **project bucket** compartido. + +La vista **Form** sigue siendo la fuente de verdad de la configuración de tu Workload: un submit actualiza todos los manifiestos generados. La vista **Advanced** es donde inspeccionas y personalizas lo que se despliega. + +## El grafo de manifiestos + +El tab **Manifests** muestra los recursos del Workload como un grafo, donde las aristas representan las relaciones entre ellos: + + + Vista Advanced del Workload con el grafo de manifiestos + + +Cada nodo muestra el nombre del manifiesto, su Kind (o el host resuelto, en los Ingress) y su origen: + +| **Origen** | **Badge** | **Significado** | +| -------------- | ------------ | ------------------------------------------------------------------------------------------------------ | +| **Managed** | `Managed` | Generado y mantenido al día por SleakOps. Las actualizaciones del template base se aplican solas. | +| **Customized** | `Customized` | Editaste su YAML. SleakOps nunca sobreescribe tu copia — ver [actualizaciones del template base](#actualizaciones-del-template-base). | +| **Custom** | `Custom` | Un manifiesto que agregaste tú. No tiene template base de SleakOps. | + +Los manifiestos deshabilitados muestran un badge `Disabled` y sus aristas se dibujan punteadas. + +Puedes arrastrar los nodos para acomodar el grafo — las posiciones se guardan por Workload, y **Reset layout** restaura el orden automático. + +Debajo del grafo, la franja **Project-shared manifests** muestra los manifiestos del [project bucket](#el-project-bucket) que se despliegan junto a todos los Workloads, con un acceso **Manage →** a la Chart Configuration del Project. + +## Editar un manifiesto + +Haz clic en cualquier nodo para abrir el editor. El header muestra el kind del manifiesto, su origen, la versión del template base, un switch **Enabled**, un botón de copiado y **Delete**. + + + Tab YAML del editor de manifiestos con el panel de variables + + +El tab **YAML** es donde editas el template. Pueden aparecer dos tipos de placeholders: + +- Las variables `<< form >>` se resuelven **antes de Helm**, con los valores del formulario de tu Workload (nombre, namespace, command, healthcheck, etc.). +- Las expresiones `{{ .Values }}` quedan para **Helm en el momento del deploy** (replicas, resources, tag de imagen — todo lo que viene de [Values](/docs/project/values)). + +El panel **Variables** de la derecha lista todo lo disponible: haz clic en una entrada para insertarla en el cursor, o arrástrala al editor. + +El editor valida mientras escribes. Los errores bloquean el guardado, e incluyen: + +- Variables desconocidas, no declaradas en el contexto del Workload. +- Expresiones bloqueadas por el sandbox de templates. +- Quitar el label protegido `sleakops.com/managed`. +- Un `namespace` distinto al del entorno del Project (warning — el namespace siempre es el del entorno). + +Guardar tu primera edición estructural convierte un manifiesto `managed` en `customized`. Si el switch **Deploy?** de la toolbar del grafo está apagado, el guardado queda registrado como un [cambio pendiente](/docs/project/deployment/pending_changes); si está prendido, se dispara un deployment al instante. + +### Preview + +El tab **Preview** renderiza el template con las variables actuales del formulario y muestra exactamente lo que se le entregará a Helm: + + + Tab Preview del editor de manifiestos con el template renderizado + + +Los badges sobre la salida confirman cuántas variables `<< form >>` se resolvieron, si quedan expresiones `{{ .Values }}` para el deploy, y que los invariantes protegidos están presentes. Si el template no renderiza, los errores se listan con su número de línea y un acceso **Fix in YAML** — un manifiesto que no renderiza no se despliega. + +## Agregar un manifiesto + +Usa **Add manifest** (en la toolbar del grafo del Workload, o en el project bucket) para desplegar recursos más allá de los generados: + + + Modal Add manifest con scope, kind y template + + +| **Campo** | **Descripción** | +| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | +| **Scope** | **This workload** (se despliega con el Workload, con variables `<< form >>` disponibles) o **Project bucket** (compartido, se despliega con cada release). | +| **Kind** | ConfigMap, Secret, ServiceAccount, NetworkPolicy, PersistentVolumeClaim, CronJob — o **Custom…** para cualquier otro kind, incluidos CRDs. | +| **Name** | El nombre del manifiesto; se refleja en el `metadata.name` del template. | +| **Depends on** | Opcional. Dibuja las aristas del grafo desde este manifiesto hacia los seleccionados. | +| **Template** | El YAML del manifiesto. Se genera un stub inicial según el Kind elegido. | + +Ten en cuenta: + +- **Los kinds cluster-scoped se rechazan**, y el `namespace` debe ser igual al del entorno del Project. +- **Los kinds custom requieren su CRD instalado en el cluster** — por ejemplo, un `ScaledObject` de Keda necesita el Addon de Keda. Si no, el deploy falla con el error correspondiente de Helm. + +## El project bucket + +Los manifiestos agregados con scope **Project bucket** no están atados a ningún Workload: se despliegan con **cada release** del Project. Los habitantes típicos son NetworkPolicies, ConfigMaps compartidos y ServiceAccounts. Se administran desde **Project → Settings → Chart Configuration → Manifests**: + + + Lanes del Explorer y el project bucket compartido + + +El **Explorer** al inicio de la sección lista cada Workload del Project con sus manifiestos, y el project bucket al final. Usa el filtro para buscar por nombre o kind; hacer clic en un Workload abre su vista Advanced, y hacer clic en un manifiesto abre el editor ahí mismo. + + + Página de Chart Configuration con la sección Manifests + + +:::warning Extends Template & Values está deprecado +La sección libre **Extends Template & Values** debajo de Manifests sigue funcionando, pero está deprecada: los recursos custom nuevos deberían agregarse como manifiestos. Ver [Extra Templates](/docs/project/chart/extra_templates). +::: + +## Actualizaciones del template base + +Cuando personalizas un manifiesto, tu copia queda fijada: SleakOps **nunca la sobreescribe**, incluso cuando el template base del que salió recibe mejoras. Cuando existe una versión base más nueva, el editor muestra un badge **update available** y un banner con un botón **View diff**: + +- Las líneas verdes son lo que agrega la base nueva. +- Las líneas rojas son tus personalizaciones, ausentes de la base. + +Desde el diff puedes elegir **Keep my version** o **Reset to v<nueva>**. **Reset to base** (también disponible en el header del editor) descarta tus ediciones estructurales, restaura el template base de SleakOps y vuelve el manifiesto a `managed`. Los valores del formulario no se ven afectados — solo rellenan variables. + +## Deshabilitar y borrar + +- **Deshabilitar** (el switch Enabled): el manifiesto se saltea en el próximo deploy pero conserva su configuración. Si el recurso ya estaba desplegado, el próximo deploy lo quita del cluster. +- **Delete**: el manifiesto deja de desplegarse y SleakOps **no lo vuelve a crear** en futuros seeds ni actualizaciones del template base. Puedes agregar un manifiesto equivalente más adelante. + +## Desplegar tus cambios + +Todos los cambios de contenido de la vista Manifests respetan el switch **Deploy?** de la toolbar: + +- **Prendido** — se dispara un deployment después de cada guardado. +- **Apagado** — los cambios se acumulan como [cambios pendientes](/docs/project/deployment/pending_changes) y se despliegan cuando los publicas. + +Las acciones de solo layout — arrastrar nodos o **Reset layout** — son cosméticas: nunca crean un cambio pendiente ni un deployment, esté como esté el switch. + +## FAQs + +
+ +### ¿Puedo modificar los templates que genera SleakOps? + +Sí. Abre la vista Advanced del Workload, haz clic en el manifiesto y edita su YAML. Tu copia pasa a customized y SleakOps nunca la sobreescribe. +
+ +
+ +### ¿Qué pasa con mis Extra Templates existentes? + +Se siguen desplegando exactamente igual que antes. La sección Extends Template & Values quedó deprecada en favor de Manifests, así que migra los recursos custom a manifiestos a medida que los toques — un manifiesto por recurso, con validación y preview en lugar de un único bloque libre. +
+ +
+ +### ¿Puedo desplegar recursos de un CRD? + +Sí — elige **Custom…** como Kind al agregar un manifiesto y define el apiVersion/kind del CRD. El CRD debe estar instalado en el cluster (por ejemplo, el ScaledObject de Keda requiere el Addon de Keda); si no, el deploy falla con el error correspondiente de Helm. +
+ +
+ +### ¿Por qué no puedo cambiar el namespace de un manifiesto? + +Cada entorno del Project se despliega en su propio Namespace de Kubernetes. Los manifiestos siempre se despliegan en el namespace del entorno — un valor distinto se rechaza para mantener los entornos aislados. +
+ +
+ +### ¿Cuál es la diferencia entre deshabilitar y borrar un manifiesto? + +Deshabilitar conserva el manifiesto y su configuración pero lo saltea al desplegar — vuelve a prender el switch para reincluirlo. Borrar lo quita definitivamente: SleakOps no lo recrea en futuras actualizaciones, aunque siempre puedes agregar un manifiesto nuevo con el mismo contenido. +
+ +
+ +### ¿Quién puede editar manifiestos? + +La edición sigue tu rol en la plataforma: los viewers ven el grafo, el YAML y los previews en modo solo lectura; los editors y admins pueden personalizar, agregar, deshabilitar y borrar manifiestos. +
diff --git a/content/docs/es/project/manifests/add-manifest-modal.png b/content/docs/es/project/manifests/add-manifest-modal.png new file mode 100644 index 0000000000..2d30d3f389 Binary files /dev/null and b/content/docs/es/project/manifests/add-manifest-modal.png differ diff --git a/content/docs/es/project/manifests/manifest-editor-preview.png b/content/docs/es/project/manifests/manifest-editor-preview.png new file mode 100644 index 0000000000..d6ae62c621 Binary files /dev/null and b/content/docs/es/project/manifests/manifest-editor-preview.png differ diff --git a/content/docs/es/project/manifests/manifest-editor-yaml.png b/content/docs/es/project/manifests/manifest-editor-yaml.png new file mode 100644 index 0000000000..e99029baa5 Binary files /dev/null and b/content/docs/es/project/manifests/manifest-editor-yaml.png differ diff --git a/content/docs/es/project/manifests/project-manifests-explorer.png b/content/docs/es/project/manifests/project-manifests-explorer.png new file mode 100644 index 0000000000..01662836a0 Binary files /dev/null and b/content/docs/es/project/manifests/project-manifests-explorer.png differ diff --git a/content/docs/es/project/manifests/project-shared-bucket.png b/content/docs/es/project/manifests/project-shared-bucket.png new file mode 100644 index 0000000000..769e61bce2 Binary files /dev/null and b/content/docs/es/project/manifests/project-shared-bucket.png differ diff --git a/content/docs/es/project/manifests/workload-advanced-manifests.png b/content/docs/es/project/manifests/workload-advanced-manifests.png new file mode 100644 index 0000000000..48e47357d1 Binary files /dev/null and b/content/docs/es/project/manifests/workload-advanced-manifests.png differ diff --git a/content/docs/es/project/values.mdx b/content/docs/es/project/values.mdx new file mode 100644 index 0000000000..0bfd4822fb --- /dev/null +++ b/content/docs/es/project/values.mdx @@ -0,0 +1,112 @@ +--- +sidebar_position: 13 +--- +import Zoom from "react-medium-image-zoom"; +import "react-medium-image-zoom/dist/styles.css"; +import { FiExternalLink } from "react-icons/fi"; + +# Values + +Cada deployment renderiza el chart de Helm de tu Project con un **árbol de values**: replicas, resources, tags de imagen, hosts, probes y todo lo demás que parametriza los [manifiestos](/docs/project/manifests). SleakOps genera esos values por ti, y te deja sobreescribirlos en tres niveles persistentes — más un cuarto nivel, efímero, en el momento del deploy. + +## Los niveles de override + +Los values se mergean nivel por nivel (deep merge) al momento del deploy. Cada nivel sobreescribe al anterior — gana el scope más específico: + +| **Nivel** | **Alcance** | **Dónde se define** | +| --------- | --------------------------------- | -------------------------------------------------------------------------------------- | +| **1** | Generados por SleakOps | En ningún lado — derivan de tus formularios de Workload, Dependencies y Var Groups (solo lectura). | +| **2** | Global del Project | **Project → Settings → Chart Configuration**, el editor de **Values**. | +| **3** | Override del Workload | El tab **Advanced → Values** del Workload (editor **Workload override**). | +| **4** | Values por deploy (efímeros) | El [CLI](/docs/cli#inyectar-values-en-el-deploy): `sleakops deploy -f values.yaml` o `--set clave.ruta=valor`. | + +Los niveles 2 y 3 son persistentes: aplican a todos los deployments siguientes hasta que los cambies. El nivel 4 aplica a **un solo deployment**. + +:::info Merge de listas +A diferencia de Helm puro, el merge entre niveles **combina las listas** en lugar de reemplazarlas — un override que redefine una lista suma entradas a las generadas en vez de descartarlas. +::: + +## El tab Values del Workload + +Abre un Workload, cambia a **Advanced** y selecciona el tab **Values**: + + + Tab Values del Workload con los values generados y el override del workload + + +- **Generated by SleakOps** (solo lectura) — los values que SleakOps derivó para este Workload desde su formulario: command, probes, resources, node selector, hosts, etcétera. +- **Workload override** — un mapping YAML que se mergea **sobre** los values generados, solo para este Workload. Guárdalo con **Save override**. + +Para los values de Ingress, cada clave bajo `hosts:` representa un dominio. Para ajustar un solo host, sobreescribe una clave dentro de esa entrada — por ejemplo `hosts..custom_service` — en lugar de redefinir el bloque entero. + +### Effective values + +La tabla **Effective values — what Helm receives** del final responde "qué se va a desplegar realmente": una fila por clave sobreescrita, con el valor que aporta cada nivel y un badge que nombra la fuente ganadora. + + + Tabla de effective values con las columnas generated, project y workload + + +En el ejemplo de arriba, `resources.limits.memory` se genera como `1331Mi`, sube a `1536Mi` por un global del Project, y termina en `2048Mi` por el override del Workload — el Workload tiene la última palabra. + +## Values globales del Project + +Los overrides a nivel Project viven en **Project → Settings → Chart Configuration**, en el editor de **Values** de la sección Extends Template & Values. El aviso de deprecación de esa sección apunta a migrar los **templates** libres a [Manifests](/docs/project/manifests) — el editor de Values sigue siendo el hogar de los globales del Project. Anida las claves bajo el nombre del Workload (o bajo `global:` para values de todo el chart): + + + Editor de values globales del Project en Chart Configuration + + +```yaml +backoffice: + resources: + limits: + memory: 1536Mi +``` + +Usa los globales del Project para valores que quieres que todos los Workloads hereden de forma consistente; usa los overrides de Workload para las excepciones. + +## Values por deploy (CLI) + +Para valores que pertenecen a un único deployment — subir réplicas para un canary, un feature flag puntual — inyéctalos desde tu pipeline con `sleakops deploy -f values.yaml`, `--set clave=valor` o `--set-string clave=valor`. Ganan sobre todos los niveles persistentes, aplican solo a ese deployment, y el próximo deploy sin esos flags vuelve a los valores de la plataforma. + +Ver [Inyectar values en el deploy](/docs/cli#inyectar-values-en-el-deploy) para la sintaxis completa y sus consideraciones. + +## FAQs + +
+ +### ¿Qué valor gana si la misma clave está definida en varios niveles? + +El más específico: los values por deploy ganan al override del Workload, que gana al global del Project, que gana al valor generado. La tabla de Effective values muestra el ganador por clave con su badge de origen. +
+ +
+ +### ¿Guardar un override dispara un deployment? + +Guardar un override de Workload registra un cambio pendiente — se despliega cuando lo publicas. En la Chart Configuration del Project decide el switch Deploy?: prendido dispara un deployment con Apply changes, apagado deja la actualización como cambio pendiente. +
+ +
+ +### ¿Cómo veo los values que un Workload va a recibir realmente? + +La tabla Effective values del tab Values del Workload muestra el resultado mergeado por clave. El tab Preview de cada manifiesto muestra dónde cae cada expresión {{ .Values }} en el template renderizado. +
+ +
+ +### ¿Debería poner secretos en los values? + +No. Los secretos van en los Var Groups, que se guardan encriptados y se inyectan como Secrets de Kubernetes. Los values son configuración del chart, no un almacén de secretos — y los flags --set/--set-string del deploy además quedan en el historial de tu shell. +
diff --git a/content/docs/es/project/values/project-global-values.png b/content/docs/es/project/values/project-global-values.png new file mode 100644 index 0000000000..96f32780cb Binary files /dev/null and b/content/docs/es/project/values/project-global-values.png differ diff --git a/content/docs/es/project/values/workload-effective-values.png b/content/docs/es/project/values/workload-effective-values.png new file mode 100644 index 0000000000..ddde944712 Binary files /dev/null and b/content/docs/es/project/values/workload-effective-values.png differ diff --git a/content/docs/es/project/values/workload-values-tab.png b/content/docs/es/project/values/workload-values-tab.png new file mode 100644 index 0000000000..cd70da8ecf Binary files /dev/null and b/content/docs/es/project/values/workload-values-tab.png differ diff --git a/content/docs/es/responsability-model.mdx b/content/docs/es/responsability-model.mdx index 177aa78bd8..515fb3136b 100644 --- a/content/docs/es/responsability-model.mdx +++ b/content/docs/es/responsability-model.mdx @@ -9,4 +9,6 @@ Utilizamos de manera transparente todos los servicios de AWS, lo que implica que Para proteger tus datos y asegurarte de que no se pierdan debido a posibles interrupciones en los servicios, es recomendable contar con políticas de respaldo. Actualmente, no ofrecemos soporte para respaldos de nuestras dependencias (RDS, S3, RabbitMQ, etc.). Para configurarlos, puedes acceder a través de tu cliente de AWS y definir tus políticas de respaldo. [Obtén más información sobre el Modelo de Responsabilidad Compartida de AWS] -(https://aws.amazon.com/compliance/shared-responsibility-model/) \ No newline at end of file +(https://aws.amazon.com/compliance/shared-responsibility-model/) + +Para ver qué cubre específicamente el soporte de SleakOps, consulta [Soporte](/docs/support). \ No newline at end of file diff --git a/content/docs/es/support.mdx b/content/docs/es/support.mdx new file mode 100644 index 0000000000..c8845c0da3 --- /dev/null +++ b/content/docs/es/support.mdx @@ -0,0 +1,37 @@ +--- +sidebar_position: 18 +--- + +# Soporte + +Si tienes un problema o una pregunta, la forma más rápida de obtener ayuda es a través de **Support**, en la barra lateral principal de la consola — combina un chat con IA y tickets de soporte para tu cuenta. Antes de escribir, vale la pena buscar aquí en la documentación: la mayoría de las preguntas del día a día ya están respondidas en un tutorial o FAQ. + +## Qué cubre nuestro soporte + +- Errores propios de la plataforma SleakOps. +- Errores en recursos de infraestructura gestionados automáticamente por SleakOps (clusters, ambientes, dependencias, addons). +- Ayuda para actualizar recursos provisionados con SleakOps. +- Bloqueos de estado de la infraestructura (recursos que quedan trabados en un estado). +- Acompañamiento con workarounds para customizaciones que la plataforma no cubre. + +## Dónde mirar primero + +Para algunas preguntas frecuentes, la respuesta más rápida es una que puedes conseguir tú mismo, ahora mismo: + +- **Algo falla en tu aplicación o en su código** — eso lo maneja y depura tu propio equipo; SleakOps administra la infraestructura sobre la que corre tu aplicación, no la aplicación en sí. Como primer paso, puedes correr un [Autodiagnóstico](/docs/powered-ai/autodiagnostic) con IA sobre el workload para orientar la investigación. +- **La aplicación se siente lenta** — empieza por [Grafana](/docs/cluster/addons/grafana) para ver qué están usando realmente tus workloads, antes de asumir que es un problema de infraestructura. +- **Preguntas sobre tu Dockerfile o la configuración del build** — consulta [Configura tu Dockerfile](/docs/project/configure_your_dockerfile) para ver qué está soportado de fábrica. +- **Quieres entender o reducir tu gasto en AWS** — consulta la [Guía de revisión de costos](/tutorial/cost-review-guide) para leer lo que ya estás gastando, y [Estrategias de optimización de costos en AWS](/tutorial/optimize-aws-costs) para formas concretas de bajarlo. +- **Elegir servicios de AWS o diseñar tu arquitectura** — consulta el [Modelo de Responsabilidad](/docs/responsability-model) más abajo y la [documentación propia de AWS](https://docs.aws.amazon.com/) como guía; estas decisiones son tuyas para tu aplicación. + +## Responsabilidad de un vistazo + +| | SleakOps | Tú | +|---|---|---| +| **Plataforma e infraestructura** | Clusters, networking, provisión, y los recursos que SleakOps crea para ti — siempre que no los modifiques directamente en AWS por fuera de la plataforma. | Configurar variables de entorno, definir requisitos de recursos y monitorear el uso. | +| **Tu aplicación** | Proveer el entorno de ejecución, pipelines de CI/CD y herramientas de observabilidad (logs/métricas). | Tu código, sus dependencias y su rendimiento | +| **Datos y backups** | Exponer la configuración de backup del recurso en el formulario de la dependencia (por ejemplo, el toggle "Automated Backup" de RDS y su período de retención). | Definir y gestionar las políticas de backup y restauración de tus dependencias — RDS, S3, RabbitMQ — y su almacenamiento seguro (ver [Modelo de Responsabilidad](/docs/responsability-model)) | + +## ¿Todavía no estás seguro? + +Si no estás seguro de si algo está cubierto, simplemente pregunta — escríbenos a través de **Support** y te vamos a orientar. diff --git a/content/pages/es/legal/privacy-policy.md b/content/pages/es/legal/privacy-policy.md new file mode 100644 index 0000000000..4da1f13421 --- /dev/null +++ b/content/pages/es/legal/privacy-policy.md @@ -0,0 +1,181 @@ +--- +title: Política de Privacidad +--- + +# Política de Privacidad de SleakOps + +**Última actualización:** 15 de mayo de 2024 + +Bienvenido a SleakOps, operado por Craftech-io, Inc. ("nosotros" o "nuestro"). Nuestro servicio, accesible desde [www.sleakops.com](https://www.sleakops.com/) ("Servicio"), se compromete a proteger su privacidad. Esta Política de Privacidad describe nuestras prácticas con respecto a la recopilación, uso y divulgación de su información a través del uso de nuestro Servicio, y aplica a todos los visitantes, usuarios y otras personas que accedan al Servicio. + +Al utilizar nuestro Servicio, usted acepta la recopilación y el uso de información de acuerdo con esta política. + +## Recopilación y Uso de Información + +Recopilamos varios tipos de información para diversos fines con el objetivo de proporcionar y mejorar nuestro Servicio. + +### Tipos de Datos Recopilados: + +### Datos Personales + +Al utilizar nuestro Servicio, podemos solicitarle que nos proporcione cierta información de identificación personal que puede utilizarse para contactarle o identificarle ("Datos Personales"). Los Datos Personales pueden incluir, entre otros: + +- Dirección de correo electrónico +- Nombre y apellidos +- Número de teléfono +- Dirección, Estado, Provincia, Código Postal, Ciudad +- Cookies y Datos de Uso + +Esta información nos permite brindarle una experiencia personalizada, responder eficazmente a sus solicitudes y mejorar nuestros servicios. + +### Datos de Uso + +Los Datos de Uso se recopilan automáticamente al utilizar el Servicio. Estos datos pueden incluir detalles como: + +- La dirección de Protocolo de Internet de su dispositivo (p. ej., dirección IP) +- Tipo y versión del navegador +- Páginas de nuestro Servicio que visita +- Fecha y hora de su visita +- Tiempo dedicado a esas páginas +- Identificadores únicos del dispositivo y otros datos de diagnóstico + +### Datos de Seguimiento y Cookies + +Utilizamos Cookies y tecnologías de seguimiento similares para rastrear la actividad en nuestro Servicio y almacenar cierta información. Estas tecnologías se utilizan para mejorar la eficiencia y facilidad de uso de nuestros servicios; nos permiten mejorar nuestro Servicio y su experiencia, permitiéndonos: + +- Recordar sus datos de inicio de sesión +- Proporcionar contenido personalizado +- Analizar cómo se utiliza nuestro Servicio +- Los tipos de cookies utilizadas pueden incluir: + +**Cookies de Sesión:** Necesarias para el correcto funcionamiento de nuestro Servicio, como permitirle iniciar sesión en áreas seguras. + +**Cookies de Preferencias:** Nos permiten recordar sus preferencias y varias configuraciones. + +**Cookies de Seguridad:** Nos ayudan a garantizar la seguridad de su cuenta. + +**Cookies de Análisis y Balizas:** Se utilizan para recopilar datos agregados sobre el tráfico del sitio web y cómo los usuarios interactúan con nuestro sitio, permitiéndonos mejorar nuestro Servicio y adaptarlo mejor a sus necesidades. + +Al utilizar el Servicio, usted consiente el uso de estas tecnologías como se describe en nuestra Política de Cookies. Tiene la opción de rechazar todas las cookies o indicar cuándo se está enviando una cookie. Sin embargo, si no acepta las cookies, es posible que no pueda utilizar algunas partes de nuestro Servicio. + +## Uso de Datos + +Utilizamos sus datos personales para operar y gestionar nuestro Servicio. Esto incluye usar su información para: + +- Registrar y gestionar su cuenta. +- Proporcionar los servicios que solicita. +- Comunicarnos con usted sobre su cuenta o los servicios que utiliza. + +### Comunicación + +Utilizamos sus datos personales para contactarle sobre actualizaciones, cambios de servicio y ofertas promocionales, si ha optado por recibir estas comunicaciones. Esto puede incluir: + +- Correos electrónicos sobre actualizaciones o cambios de servicio. +- Correos electrónicos promocionales, si ha aceptado recibirlos. + +### Mejora del Servicio + +Analizamos cómo utiliza nuestros servicios para ayudarnos a mejorarlos y desarrollarlos, y para mejorar su experiencia general. Esto implica: + +- Analizar patrones de uso para identificar mejoras. +- Probar nuevas funciones. + +### Cumplimiento y Aplicación + +Utilizamos sus datos para cumplir con las obligaciones legales y hacer cumplir nuestros términos, incluyendo: + +- Responder a solicitudes legales o prevenir el fraude. +- Garantizar la seguridad de nuestros servicios. + +### Compartir Sus Datos + +Podemos compartir sus datos con: + +- Proveedores de servicios que nos ayudan con partes de nuestras operaciones comerciales. +- Autoridades legales cuando lo exija la ley. +- Otras partes en relación con una transacción comercial como una fusión o venta. + +## Transferencia de Datos + +Su información, incluidos los Datos Personales, puede transferirse a — y mantenerse en — computadoras ubicadas fuera de su estado, provincia, país u otra jurisdicción gubernamental donde las leyes de protección de datos pueden diferir de las de su jurisdicción. + +Su consentimiento a esta Política de Privacidad, seguido del envío de dicha información, representa su acuerdo con esa transferencia. + +Tomaremos todos los pasos razonablemente necesarios para garantizar que sus datos se traten de forma segura y de acuerdo con esta Política de Privacidad, y no se realizará ninguna transferencia de sus Datos Personales a una organización o país a menos que existan controles adecuados, incluida la seguridad de sus datos y otra información personal. + +## Divulgación de Datos + +Podemos divulgar sus Datos Personales en la creencia de buena fe de que dicha acción es necesaria para: + +### Transacciones Comerciales + +Si la Empresa participa en una fusión, adquisición o venta de activos, sus Datos Personales pueden ser transferidos. Le notificaremos antes de que sus Datos Personales sean transferidos y queden sujetos a una Política de Privacidad diferente. + +### Aplicación de la ley + +En determinadas circunstancias, la Empresa puede estar obligada a divulgar sus Datos Personales si así lo exige la ley o en respuesta a solicitudes válidas de autoridades públicas (p. ej., un tribunal o una agencia gubernamental). + +### Otros requisitos legales + +La Empresa puede divulgar sus Datos Personales en la creencia de buena fe de que dicha acción es necesaria para: + +- Cumplir con una obligación legal +- Proteger y defender los derechos o la propiedad de la Empresa +- Prevenir o investigar posibles irregularidades en relación con el Servicio +- Proteger la seguridad personal de los Usuarios del Servicio o del público +- Proteger contra la responsabilidad legal + +## Seguridad de los Datos + +La seguridad de sus datos es importante para nosotros, pero recuerde que ningún método de transmisión a través de Internet o método de almacenamiento electrónico es 100% seguro. No podemos garantizar su seguridad absoluta. + +## Proveedores de Servicios + +Podemos contratar empresas e individuos externos para facilitar nuestro Servicio ("Proveedores de Servicios"), para proporcionar el Servicio en nuestro nombre, para realizar servicios relacionados con el Servicio, o para ayudarnos a analizar cómo se utiliza nuestro Servicio. + +Estos terceros tienen acceso a sus Datos Personales únicamente para realizar estas tareas en nuestro nombre y están obligados a no divulgarlos ni utilizarlos para ningún otro propósito. + +### Herramientas CI/CD + +Podemos utilizar Proveedores de Servicios externos para automatizar el proceso de desarrollo de nuestro Servicio. + +GitLab CI/CD es proporcionado por GitLab, Inc.: + +- El servicio GitLab CI (Integración Continua) es parte de GitLab que construye y prueba el software cada vez que un desarrollador envía código a la aplicación. +- GitLab CD (Despliegue Continuo) es un servicio de software que coloca los cambios de cada código en producción, lo que resulta en un despliegue diario en producción. + +Para más información sobre qué datos recopila GitLab CI/CD, con qué propósito y cómo se garantiza la protección de los datos, visite la página de Política de Privacidad de GitLab CI/CD: https://about.gitlab.com/privacy/. + +### Pagos + +Podemos proporcionar productos y/o servicios de pago dentro del Servicio. En ese caso, utilizamos servicios de terceros para el procesamiento de pagos (p. ej., procesadores de pago). + +No almacenaremos ni recopilaremos los detalles de su tarjeta de pago. Esa información se proporciona directamente a nuestros procesadores de pago externos, cuyo uso de su información personal se rige por su Política de Privacidad. + +Estos procesadores de pago cumplen con los estándares establecidos por PCI-DSS según lo gestiona el Consejo de Estándares de Seguridad PCI, que es un esfuerzo conjunto de marcas como Visa, Mastercard, American Express y Discover. Los requisitos de PCI-DSS ayudan a garantizar el manejo seguro de la información de pago. + +Los procesadores de pago con los que trabajamos son: + +- Stripe: Su Política de Privacidad se puede consultar en https://stripe.com/us/privacy + +## Enlaces a Otros Sitios Web + +Nuestro Servicio puede contener enlaces a sitios web o servicios de terceros que no son propiedad ni están controlados por Craftech-io, Inc. + +No tenemos control ni asumimos ninguna responsabilidad por el contenido, las políticas de privacidad o las prácticas de sitios web o servicios de terceros. + +Le recomendamos encarecidamente que lea los términos y condiciones y las políticas de privacidad de cualquier sitio web o servicio de terceros que visite. + +## Restricciones de Edad + +Nuestro Servicio está dirigido únicamente a personas mayores de 18 años. Si tiene menos de 18 años, no utilice el Servicio. + +## Cambios en la Política de Privacidad + +Nos reservamos el derecho, a nuestra sola discreción, de modificar o reemplazar esta Política de Privacidad en cualquier momento. Es su responsabilidad revisar esta Política de Privacidad periódicamente. + +Al continuar accediendo o utilizando nuestro Servicio después de que esas revisiones entren en vigencia, acepta estar sujeto a la Política de Privacidad revisada. + +## Contáctenos + +Si tiene alguna pregunta sobre esta Política de Privacidad, contáctenos: contact@sleakops.com diff --git a/content/pages/es/legal/terms-and-conditions.md b/content/pages/es/legal/terms-and-conditions.md new file mode 100644 index 0000000000..d4f1453894 --- /dev/null +++ b/content/pages/es/legal/terms-and-conditions.md @@ -0,0 +1,211 @@ +--- +title: Términos y Condiciones +--- + +# Términos y Condiciones + +**Última actualización:** 15 de mayo de 2024 + +## Introducción + +Bienvenido a [www.sleakops.com](http://www.sleakops.com/) ("Sitio Web"), un servicio proporcionado por Craftech-io, Inc. ("Empresa", "nosotros" o "nuestro"). La Empresa tiene su sede en 651 North Broad Street, Middletown, Delaware, EE.UU. + +Estos Términos y Condiciones ("Términos") rigen su acceso y uso de nuestro Sitio Web y sus servicios asociados (colectivamente, "Servicio"). Al acceder o utilizar cualquier parte de nuestro Servicio, usted ("Usuario", "usted") acepta estar sujeto a estos Términos y nuestra [Política de Privacidad](/legal/privacy-policy). Si no está de acuerdo con todos los términos y condiciones de este acuerdo, no podrá acceder al Sitio Web ni utilizar ningún servicio. + +Lea estos Términos detenidamente antes de acceder a nuestro Servicio. Estos Términos se aplican a todos los visitantes, usuarios y otras personas que acceden o utilizan el Servicio. Al aceptar estos Términos, declara que tiene al menos 18 años de edad o la edad legal para celebrar un contrato vinculante según las leyes aplicables. Si accede y utiliza el Servicio en nombre de una empresa, organización u otra entidad legal, declara y garantiza que tiene la autoridad para vincular dicha entidad a estos Términos. + +Su acceso y uso del Servicio está condicionado a su aceptación y cumplimiento de estos Términos. Estos Términos son importantes y afectan sus derechos legales, por lo que le rogamos que los lea detenidamente. + +## Comunicaciones + +Al crear una cuenta en nuestro Servicio, acepta suscribirse a boletines informativos, materiales de marketing o promocionales y otra información que podamos enviarle. Sin embargo, puede cancelar estas comunicaciones siguiendo el enlace de cancelación de suscripción o enviando un correo electrónico a [contact@sleakops.com](mailto:contact@sleakops.com). + +## Responsabilidades de la Cuenta + +Debe registrarse para obtener una cuenta para acceder y utilizar ciertas funciones de nuestro Servicio. Al crear una cuenta, acepta: + +- Proporcionar información precisa, completa y actualizada según se solicita en el formulario de registro. +- Actualizar su información para mantener su precisión y exhaustividad. +- Aceptar todos los riesgos asociados con el acceso no autorizado a su cuenta como resultado de su acción u omisión. + +### Seguridad de la Cuenta + +Usted es responsable de proteger la contraseña que utiliza para acceder a nuestro Servicio y de cualquier actividad o acción bajo su cuenta, ya sea que su contraseña sea con nuestro Servicio o un servicio de terceros. Usted acepta: + +- Mantener su contraseña segura y confidencial. +- Notificarnos inmediatamente al tener conocimiento de cualquier violación de seguridad o uso no autorizado de su cuenta. +- No divulgar su contraseña a terceros. +- Su cuenta es personal y no puede transferirla ni ponerla a disposición de otros. Usted es responsable de todas las actividades que ocurran bajo su cuenta, ya sea que las conozca o no. + +### Restricciones de la Cuenta + +No debe utilizar la cuenta de otro usuario ni la información de registro de nuestro Servicio sin permiso. Del mismo modo, no puede permitir que nadie más use su cuenta. No puede usar su cuenta para participar en ninguna actividad ilegal o con fines fraudulentos ni para infringir los derechos de otros. + +### Terminación y Suspensión + +Nos reservamos el derecho de suspender o cancelar su cuenta, rechazar cualquier uso actual o futuro de nuestro Servicio, y no proporcionarle ningún servicio si: + +- Incumple cualquier término de estos Términos y Condiciones. +- No podemos verificar o autenticar ninguna información que nos proporcione. +- Creemos que sus acciones pueden causar responsabilidad legal para usted, nuestros usuarios o nosotros. +- Usted es responsable de cualquier contenido que cree, transmita o muestre mientras utiliza nuestro Servicio y de las consecuencias de sus acciones al hacerlo. + +Tras la terminación, su derecho a utilizar el Servicio cesará inmediatamente, y cualquier dato o contenido almacenado en su cuenta puede ser inaccesible. + +## Compras + +Cuando desee adquirir cualquier servicio disponible, es posible que se le solicite que proporcione cierta información relevante para su compra, incluyendo, entre otras cosas, el número de su tarjeta de crédito, la fecha de vencimiento de su tarjeta de crédito, su dirección de facturación y otra información de pago. + +Todos los servicios enumerados están sujetos a aceptación y disponibilidad. Podemos rechazar o ser incapaces de procesar su reserva si: + +- El servicio que seleccionó ya no está disponible. +- Hay un error en el precio o la descripción del servicio. + +Usted declara y garantiza que: + +- Tiene el derecho legal de utilizar cualquier tarjeta(s) de crédito u otro(s) método(s) de pago en relación con cualquier compra. +- La información que nos proporciona es verdadera, correcta y completa. + +## Suscripciones + +Los detalles de los diferentes tipos de suscripción, servicios incluidos y precios están disponibles en nuestro Sitio Web y en la Plataforma AWS. Puede seleccionar la suscripción que mejor se adapte a sus necesidades. + +### Inscripción en la Suscripción a través de AWS Marketplace + +La suscripción a la plataforma SleakOps se facilita a través del Mercado de AWS (Amazon Web Services). Al suscribirse, acepta que AWS le facture por el uso de los servicios de SleakOps. La suscripción se renovará automáticamente al final de cada período de facturación, a menos que usted o SleakOps cancelen la suscripción. + +### Información de Pago y Facturación + +Toda la facturación de los servicios de SleakOps será procesada por AWS. Los cargos por nuestros servicios aparecerán como un elemento separado en su factura de AWS. SleakOps no es responsable de la facturación ni de los detalles específicos de las transacciones gestionadas a través del Mercado de AWS. Al proporcionar un método de pago aceptado por AWS, confirma que está autorizado para usar el método de pago designado y que nos permite cargar su método de pago por el importe total de su suscripción, incluidos los impuestos aplicables y otros cargos. + +### Facturación de la Cuenta AWS + +Los servicios de SleakOps aparecerán como un cargo separado en la factura de su cuenta AWS. No somos responsables de la facturación ni de los detalles específicos de las transacciones realizadas a través del Mercado de AWS. + +### Términos y Condiciones de AWS + +Al utilizar SleakOps, reconoce que la plataforma utiliza AWS como proveedor de servicios en la nube. Por lo tanto, también acepta cumplir con los Términos y Condiciones de AWS, que se incorporan por referencia en estos [Términos y Condiciones de SleakOps](https://aws.amazon.com/legal/?nc1=f_cc). Es su responsabilidad revisar y cumplir con los Términos y Condiciones de AWS. + +### Renovación y Cancelación + +Puede cancelar su suscripción en cualquier momento a través de la configuración de su cuenta en la plataforma SleakOps, a través de la configuración de su cuenta AWS, o contactándonos. Tras la cancelación, su suscripción permanecerá activa hasta el final del período de facturación actual, pero no se le cobrará por el siguiente período. No recibirá un reembolso por los días restantes en su ciclo de facturación actual. Es importante cancelar su suscripción antes de que se renueve si no desea ser cobrado por el siguiente ciclo de facturación. + +### Cambios en los Planes de Suscripción + +Nos reservamos el derecho de modificar, cancelar o enmendar de otro modo nuestros planes de suscripción ofrecidos. En caso de modificación de un plan, le proporcionaremos un aviso razonable con anticipación por correo electrónico o mediante un aviso en nuestro Sitio Web. Si no está de acuerdo con los cambios, puede cancelar su suscripción como se describe anteriormente. + +### Pruebas Gratuitas + +Podemos ofrecer un período de prueba gratuita para una suscripción a nuestros servicios. A menos que cancele antes del final del período de prueba, las tarifas de suscripción regulares se aplicarán después de que finalice el período de prueba. Los detalles y condiciones de cualquier prueba gratuita se comunicarán en el momento del registro. + +### Terminación por Nuestra Parte + +Nos reservamos el derecho de cancelar su suscripción si no paga las tarifas de suscripción o de otro modo no cumple con ninguno de los términos de este Acuerdo. En tales casos, no tendrá derecho a ningún reembolso. + +## Contenido en la Plataforma + +Nuestro Servicio le permite publicar, vincular, almacenar, compartir y poner a disposición de otro modo cierta información, texto, gráficos, videos u otros materiales ("Contenido"). Usted es totalmente responsable del Contenido que cargue, comparta o ponga a disposición a través del Servicio, incluida su legalidad, fiabilidad y pertinencia. + +Al publicar Contenido en o a través del Servicio, declara y garantiza que: + +- El Contenido es suyo o tiene los derechos necesarios para usarlo y otorgarnos los derechos y licencias descritos en estos Términos. +- La publicación de su Contenido no infringe los derechos de privacidad, publicidad, derechos de autor, derechos contractuales ni ningún otro derecho de ninguna persona o entidad. + +### Moderación de Contenido + +SleakOps tiene el derecho, pero no la obligación, de monitorear y editar o eliminar cualquier Contenido proporcionado por los usuarios. Podemos eliminar o restringir el acceso a cualquier Contenido publicado en o a través del Servicio en cualquier momento y sin previo aviso si creemos que viola nuestras políticas o la ley. También nos reservamos el derecho de cancelar la cuenta de cualquier persona que se encuentre infringiendo un derecho de autor. + +### Responsabilidad por el Contenido + +Usted retiene todos y cada uno de sus derechos sobre cualquier Contenido que envíe, publique o muestre en o a través del Servicio y es responsable de proteger esos derechos. No asumimos ninguna responsabilidad por el Contenido que usted o cualquier tercero publique en o a través del Servicio. + +## Usos Prohibidos + +Al utilizar nuestro Servicio, tiene prohibido participar en las siguientes actividades: + +- Utilizar el Servicio para fines ilegales o en aras de actividades ilegales. Los usuarios internacionales aceptan cumplir con todas las leyes locales sobre conducta en línea y contenido aceptable. +- Publicar o distribuir contenido que infrinja cualquier otra propiedad intelectual, privacidad o derecho de publicidad de otro. +- Transmitir virus, malware u otros tipos de software malicioso, o enlaces a dicho software, a través del Servicio. +- Participar en actividades que interrumpan, socaven o manipulen la integridad o funcionalidad de cualquier sistema informático o red utilizada por SleakOps y sus usuarios. +- Usar bots, arañas u otros métodos automatizados para acceder al Servicio para cualquier propósito sin nuestro permiso expreso por escrito. +- Eludir las medidas que podamos usar para prevenir o restringir el acceso al Servicio, incluidas las funciones que previenen o restringen el uso o la copia de cualquier contenido o imponen limitaciones al uso del Servicio o del contenido del mismo. +- Intentar interferir, comprometer la integridad o seguridad del sistema, o descifrar cualquier transmisión hacia o desde los servidores que ejecutan el Servicio. +- Tomar cualquier acción que imponga, o pueda imponer a nuestra sola discreción, una carga irrazonable o desproporcionadamente grande en nuestra infraestructura. + +### Actividades Comerciales y/o Ventas No Autorizadas + +- Utilizar el Servicio para cualquier propósito de solicitud comercial, sin el permiso previo por escrito de SleakOps. +- Anunciar u ofrecer vender o comprar cualquier bien o servicio para cualquier propósito comercial que no esté específicamente autorizado. + +### Información Falsa + +Crear u operar una identidad falsa en el Servicio, hacerse pasar por otra persona o entidad, o falsificar su afiliación con una persona o entidad. + +### Acoso y Abuso + +- Participar en cualquier comportamiento que restrinja o inhiba a cualquier otro usuario de usar o disfrutar del Servicio, o que, según lo determinemos nosotros, pueda perjudicar a SleakOps o a los usuarios del Servicio o exponerlos a responsabilidad. +- Publicar o divulgar información privada de otras personas sin su autorización y permiso expreso. + +### Infracción de Derechos de Autor + +- Cargar, publicar, alojar o transmitir correos electrónicos no solicitados, SMS o mensajes de "spam". +- Cargar, publicar, alojar o transmitir cualquier contenido que incluya código que esté oculto o contenido de otro modo de forma subrepticia dentro del contenido que no esté relacionado con el contenido. + +Estas actividades están estrictamente prohibidas y pueden resultar en la terminación inmediata de su acceso al Servicio, acciones legales contra usted y posibles sanciones civiles y/o penales según la ley aplicable. Nos reservamos el derecho de investigar incidentes y perseguir a cualquier usuario que haya participado en dichas infracciones. + +## Análisis + +Podemos utilizar Proveedores de Servicios externos para monitorear y analizar el uso de nuestro Servicio. + +- New Relic +- Data Dog + +## Propiedad Intelectual + +Todo el contenido, las funciones y la funcionalidad del Servicio, incluidos texto, gráficos, logotipos, iconos, imágenes, clips de audio, descargas digitales, compilaciones de datos y software, son propiedad de Craftech-io, Inc., sus afiliados o sus proveedores de servicios, y están protegidos por las leyes internacionales de derechos de autor y propiedad intelectual. El uso no autorizado puede dar lugar a sanciones civiles y penales. + +## Restricciones de Edad + +Nuestro Servicio está destinado únicamente a personas que tengan al menos 18 años de edad. Si tiene menos de 18 años, no utilice el Servicio. + +## Enlaces a Otros Sitios Web + +Nuestro Servicio puede contener enlaces a sitios web o servicios de terceros que no son propiedad ni están controlados por Craftech-io, Inc. + +No tenemos control ni asumimos ninguna responsabilidad por el contenido, las políticas de privacidad o las prácticas de sitios web o servicios de terceros. + +Le recomendamos encarecidamente que lea los términos y condiciones y las políticas de privacidad de cualquier sitio web o servicio de terceros que visite. + +## Terminación + +Podemos cancelar o suspender su acceso a nuestro Servicio de inmediato, sin previo aviso ni responsabilidad, por cualquier motivo, incluso si incumple los Términos. Tras la terminación, su derecho a utilizar el Servicio cesará de inmediato. Si desea cancelar su cuenta, simplemente puede dejar de usar el Servicio. + +## Ley Aplicable + +Estos Términos se regirán e interpretarán de acuerdo con las leyes de Delaware, Estados Unidos, sin tener en cuenta sus disposiciones sobre conflicto de leyes. El hecho de que no apliquemos algún derecho o disposición de estos Términos no se considerará una renuncia a esos derechos. + +## Cambios en los Términos + +Nos reservamos el derecho, a nuestra sola discreción, de modificar o reemplazar estos Términos en cualquier momento. Es su responsabilidad revisar estos Términos periódicamente. + +Al continuar accediendo o utilizando nuestro Servicio después de que esas revisiones entren en vigencia, acepta estar sujeto a los términos revisados. + +## Exención de Responsabilidad y Limitación de Responsabilidad + +### Exención de Garantías y Fuerza Mayor + +En ningún caso Craftech-io, Inc. o sus proveedores serán responsables de cualquier pérdida consecuente sufrida o incurrida por usted o cualquier tercero derivada del uso o la imposibilidad de usar este Servicio, incluso si se ha notificado a Craftech-io, Inc. o a un representante autorizado, de forma oral o escrita, de la posibilidad de dicho daño. + +### Exención "TAL CUAL" y "SEGÚN DISPONIBILIDAD" + +Los servicios proporcionados por SleakOps.com están disponibles "TAL CUAL" y "SEGÚN DISPONIBILIDAD" sin ninguna garantía o garantías, ya sea expresa o implícita. Craftech-io, Inc. renuncia a todas las garantías, incluidas, entre otras, las garantías implícitas de comerciabilidad, idoneidad para un propósito particular y no infracción. + +No garantizamos que el servicio sea ininterrumpido, oportuno, seguro o libre de errores, que se corrijan los defectos, o que el servicio o el servidor que lo pone a disposición estén libres de virus u otros componentes dañinos. El uso de nuestros servicios es bajo su propio riesgo. + +### Fuerza Mayor + +Craftech-io, Inc. no será responsable de ningún incumplimiento de sus obligaciones bajo estos Términos cuando dicho incumplimiento resulte de cualquier causa fuera del control razonable de Craftech-io, Inc., incluidos, entre otros, fallos o degradación mecánica, electrónica o de comunicaciones, actos de Dios, desastres naturales, pandemia o epidemia, terrorismo, guerra o cualquier restricción gubernamental. Dichos eventos de fuerza mayor pueden resultar en que el Servicio no esté disponible temporalmente, y nos comprometemos a hacer todos los esfuerzos razonables para mitigar la situación y restaurar el Servicio lo antes posible. + +## Contáctenos + +Si tiene alguna pregunta sobre estos Términos, contáctenos: [contact@sleakops.com](mailto:contact@sleakops.com) diff --git a/content/tutorials/en/amazon-ses.mdx b/content/tutorials/en/amazon-ses.mdx index 5245ecdf1b..f4fba74b45 100644 --- a/content/tutorials/en/amazon-ses.mdx +++ b/content/tutorials/en/amazon-ses.mdx @@ -16,9 +16,17 @@ import { FiExternalLink } from "react-icons/fi"; Configure Amazon Simple Email Service (SES) to send emails from your application, starting from sandbox mode and moving to production. +:::info +**Amazon SES is configured per AWS account.** If your SleakOps environments run across multiple AWS accounts, each account needs its own SES setup. + +**Recommendation:** keep your development account in sandbox mode — if you use a staging environment, it should share that same development account. Only your production account should request production access. + +Verify your organization's own domain (e.g., `mycompany.com`) in the development account so your team can send test emails without affecting the production sending reputation. +::: + ## Prerequisites -- Access to the AWS Console with permissions to manage SES +- Access to the AWS account where you want to configure SES - A domain or email address you want to send from - If using a domain: access to your DNS provider to add verification records @@ -35,7 +43,7 @@ All new SES accounts start in **sandbox mode**, which only allows sending to and - **Domain** — verifies the entire domain (recommended for production). AWS provides DNS records (TXT/CNAME) to add at your DNS provider. :::tip -Verify your production domain early — you can reuse the same verified domain when you move out of sandbox. +In development, verify your organization's own domain early. This lets your team send test emails to any address within that domain without needing individual verifications. ::: ### Step 2 — Send a test email in sandbox @@ -46,7 +54,7 @@ Use the SES console **Send test email** button or the AWS CLI to confirm your se ### Step 3 — Request production access -To send to any recipient, you need to exit sandbox mode. +To send to any recipient, you need to exit sandbox mode. **Only do this in your production account.** **Before submitting the request:** diff --git a/content/tutorials/en/cost-review-guide.mdx b/content/tutorials/en/cost-review-guide.mdx new file mode 100644 index 0000000000..62498a59a6 --- /dev/null +++ b/content/tutorials/en/cost-review-guide.mdx @@ -0,0 +1,124 @@ +--- +title: How to Review Your SleakOps Costs +sidebar_label: Cost Review Guide +sidebar_position: 48 +description: A practical walkthrough of the SleakOps Cost Explorer, Kubecost, and Cost Allocation Tags — how to read what you're already spending before deciding what to optimize. +tags: + - billing + - cost-analysis + - kubecost + - monitoring +image: /img/tutorials/cost-review-guide/cost-explorer-dashboard.png +--- + +import Zoom from "react-medium-image-zoom"; +import "react-medium-image-zoom/dist/styles.css"; +import { FiExternalLink } from "react-icons/fi"; + +Learn how to read your AWS spend inside SleakOps — where to look, how to drill down to the resource that's driving a cost, and what to check first when a number looks off. + +## Why Review Your Costs Regularly + +AWS spend changes as your infrastructure changes: a new environment, an autoscaled workload, a nodepool running more On-Demand nodes than expected. Checking the Cost Explorer on a regular cadence — weekly or at least once a month — lets you catch that drift while it's still a small number, instead of finding out at the end of the month. + +This guide covers **reading and interpreting** what you're already spending. If you're looking for ways to actively cut costs, see [AWS Cost Optimization Strategies](/tutorial/optimize-aws-costs) and the [Cost Optimization Strategies](/tutorial/nodepool-strategies#cost-optimization-strategies) section of the Nodepool Strategies guide. + +--- + +## The Cost Explorer (`/billing`) + +The Cost Explorer is the main place to review spend across every AWS account connected to your company. + +**Getting there** — any of these: +- Click **Go to Cost Explorer** on the cost card in the main Dashboard. +- Open the detail view of a **Cluster**, **Project**, or **Dependency** and click its **Cost Explorer** button — this opens the Cost Explorer pre-filtered to that specific resource. + + + SleakOps Cost Explorer dashboard showing the AWS account cards and the cost chart grouped by resource type + + +**Account cards** — one per AWS account (production, development, management), each showing: +- Current month cost. +- Forecast month cost (projected total for the current month based on spend so far). +- Variation versus the previous month. + +**Filters:** + +| Filter | Options | +|---|---| +| **Date range** | Last 7 days, Last 30 days, Last 90 days, This month, Last month, Last quarter, or a custom range | +| **Group by** | day, week, month | +| **Resource type** | Cluster, Environment, NodePool, Addon, ProjectEnv, Dependency | + +**Drill-down** — click a bar in the chart to go one level deeper: account → resource type → individual resource (a specific cluster, dependency, or project environment). Click **View Resources** to open the full, paginated list of resources behind the current selection, with name, date, cost, account, and resource type. + + + Cost Explorer drill-down showing the per-resource cost list after clicking a bar in the chart + + +**Exporting** — use **Export CSV** to download the resource list, or **Export PDF** to download a summary that includes the chart. + +--- + +## Going Deeper at the Cluster Level with Kubecost + +The Cost Explorer's Resource type filters stop at the SleakOps object level (cluster, project environment, dependency, etc.). To break costs down further — by Kubernetes namespace, pod, deployment, or node — install the [Kubecost](/docs/cluster/addons/kubecost) addon on the cluster. + +Once **Resource type** is set to **Cluster** and a cluster is selected, the Cost Explorer shows a Kubecost tag: +- If Kubecost is installed, the tag opens its dashboard, filtered to that cluster's cost details. +- If it isn't installed yet, the tag links to the addon installation form. + +Kubecost's own dashboard is where you'll find the `idle` cost metric — capacity you're paying for but not using — and per-namespace, per-node, and storage cost breakdowns. See the [Kubecost documentation](/docs/cluster/addons/kubecost) for how to read that dashboard. + +--- + +## The AI-Powered Cost Optimization Report + +Beyond the manual review, SleakOps can generate a cost optimization report for you using AI. It's a good complement on a longer cadence — every quarter or semester — when you want a consolidated picture with recommendations instead of walking the dashboards yourself. + +To generate one: + +1. Go to **Settings → Reports** and click **Create Report**. +2. In the support drawer, pick the **"Informe de Costos"** card and confirm with **Generate Report**. +3. The report is generated inside a support conversation — once it's ready, it shows up in the Reports list. Use **Open report** to view it in a new tab; from there you can print it or save it as PDF. + +The report includes a detailed AWS cost breakdown by service, spend trends over the last 3 months, and optimization recommendations. If you're specifically after Kubernetes right-sizing, the **"Análisis de Overprovisioning K8s"** report in the same catalog compares your workloads' requests against actual usage and suggests adjustments. + +Two things to keep in mind: + +- Generating a report has a variable AI cost depending on the complexity of the analysis, drawn from your company's monthly AI budget (configurable in Settings). +- The Reports section is available to admin and editor users with the feature enabled — if you don't see it in Settings, ask us through **Support**. + +--- + +## Where Your Costs Come From + +The Cost Explorer tells you *how much* and *where*; these pages explain *why* a resource costs what it costs: + +- **Nodepool strategy** (Spot vs. On-Demand vs. Reserved, ARM vs. AMD) — see [Node Pools](/docs/cluster/nodepools) and the [Nodepool Strategies](/tutorial/nodepool-strategies) tutorial. +- **Workload sizing** (CPU/Memory requests, autoscaling limits) — a workload's requests are the floor of what it reserves, and drive most of its Kubecost `idle` cost when they're set higher than actual usage. See [Web Service](/docs/project/workload/webservice) configuration. +- **Cluster uptime** — if a cluster doesn't need to run 24/7, a [scheduled shutdown](/docs/cluster/shutdown-cluster) stops charging for that time window. + +--- + +## If You Don't See a Cost Breakdown + +The per-resource breakdown in the Cost Explorer depends on **Cost Allocation Tags** being active in the AWS account. SleakOps enables these automatically during onboarding, but AWS can take a few days to propagate them, and in some accounts the activation needs a manual nudge. + +If they aren't active yet, the Cost Explorer for that account only shows the account's total daily cost, with no resource-level split. If that's the case: + +1. Check for a notification titled **"CostAllocationTags are not active in your AWS root account"** — it links directly to the AWS Cost Management console. +2. Follow the link and activate the tags listed there (`Model`, `Name`, `Cluster`, `ClusterId`, `Environment`, `Dependency`). +3. The breakdown becomes available once AWS finishes propagating the tags — this isn't instant, so expect a short delay. + +--- + +## Next Step: Reducing What You Spend + +Once you know where your spend is going, [AWS Cost Optimization Strategies](/tutorial/optimize-aws-costs) and the [Nodepool Strategies](/tutorial/nodepool-strategies) tutorial walk through concrete ways to bring it down — Spot instances, right-sizing, Graviton, storage lifecycle policies, and more. diff --git a/content/tutorials/en/deploy-datadog-operator.mdx b/content/tutorials/en/deploy-datadog-operator.mdx index c6b98353a0..ed89ec1961 100644 --- a/content/tutorials/en/deploy-datadog-operator.mdx +++ b/content/tutorials/en/deploy-datadog-operator.mdx @@ -1,7 +1,7 @@ --- title: Deploy Datadog Operator and DatadogAgent on SleakOps sidebar_label: Deploy Datadog Operator -sidebar_position: 33 +sidebar_position: 34 description: Install the Datadog Operator (v2.8.0) and deploy a DatadogAgent (v7.63.3) on a SleakOps EKS cluster with Karpenter NodePool tolerations, APM, log collection, and admission controller. tags: - kubernetes @@ -17,6 +17,10 @@ import { FiExternalLink } from "react-icons/fi"; Install the [Datadog Operator ](https://docs.datadoghq.com/containers/datadog_operator/) and deploy a `DatadogAgent` custom resource on a SleakOps EKS cluster to enable APM, log collection, and Kubernetes event monitoring. +:::info +This is the **advanced** Datadog setup: the Operator manages the agent lifecycle via CRDs, enables auto-instrumentation through the admission controller, and includes Karpenter NodePool tolerations. For a simpler setup without those features, use the [Helm-based guide](/tutorial/install-datadog) instead. +::: + :::info This guide was tested with **DatadogOperator v2.8.0** and **DatadogAgent v7.63.3**. ::: diff --git a/content/tutorials/en/environment-exhaustive-testing-guide.mdx b/content/tutorials/en/environment-exhaustive-testing-guide.mdx index 1c60a780ac..86b3336ecc 100644 --- a/content/tutorials/en/environment-exhaustive-testing-guide.mdx +++ b/content/tutorials/en/environment-exhaustive-testing-guide.mdx @@ -1,8 +1,457 @@ --- -title: Exhautive testing guide -sidebar_label: Exhautive testing guide +title: Exhaustive Environment Testing Guide +sidebar_label: Exhaustive Testing Guide sidebar_position: 4 -description: How can I thoroughly test my application to validate an environment? +description: A comprehensive checklist of tests to validate that your application is fully functional after migrating to a new SleakOps infrastructure. +tags: + - kubernetes + - aws + - performance + - security + - monitoring + - deployment --- -Comming soon +import Zoom from "react-medium-image-zoom"; +import "react-medium-image-zoom/dist/styles.css"; +import { FiExternalLink } from "react-icons/fi"; + +A comprehensive checklist of tests to validate that your application is fully functional after migrating to a new SleakOps infrastructure. + +## Before You Run Any Test: Cost vs. Risk + +Each section in this guide has a cost: preparation time, infrastructure overhead, and development effort. Before running a section, evaluate whether the risk it addresses is real for your application and whether the investment is proportional. + +Sometimes the same risk can be managed at a lower cost. Instead of building a full load-testing suite, for example, any monitoring stack you already have in place can let you act proactively before performance degrades and reaches your users. Observability is covered in [Section 6 — Observability and Alerts](#section-6-observability-and-alerts). + +Think of this guide as a menu. Pick the sections that match your risk tolerance and application criticality — you don't have to run everything. + +:::info +Not every section applies to every application. Run the sections that match your setup — if your application doesn't use Spot nodes or background workers, skip those sections. What matters is that you cover everything that does apply. +::: + +## Prerequisites + +- Your application is deployed in a SleakOps Environment with at least one Project +- Your Environment has finished deploying (all workloads in `CREATED` state) +- You have access to the SleakOps Console + +## Step 0: Download Your Environment Checklist + +Before running any tests, download the checklist for your Environment from the SleakOps Console. It lists every configured component — Web Services, Workers, Cron Jobs, Hooks, Dependencies, and Var Groups — so you can use it as an inventory while going through the sections below. + +Navigate to your Environment in the Console and click the **Download checklist** button. Open the downloaded Markdown file and keep it open alongside this guide. + +{/* TODO: screenshot - Environment page with the "Download checklist" button highlighted */} + +## Section 1: Functional Tests + +**Applies to:** all applications. + +These are the baseline checks. If anything here fails, fix it before moving on. + +### Web Services + +For each Web Service listed in your checklist: + +1. Open the service URL and verify it responds correctly (no error pages, no blank screen) +2. Log in and log out — verify authentication and session handling work as expected +3. Walk through the main flows of your application (the ones your users do most often) +4. Verify that the application is reading configuration from the new environment — not pointing to old databases or external services from a previous deployment + +### Workers + +For each Worker listed in your checklist: + +1. Trigger an action in your application that enqueues a background job (for example: send an email, process an upload, run a report) +2. Confirm the job completes successfully — check your application's job status UI, logs, or the result you expect + +### Cron Jobs + +For each Cron Job listed in your checklist: + +1. In [Headlamp ](https://headlamp.dev/) (available as an addon in your SleakOps Cluster), navigate to **Workloads → CronJobs** in your Environment's namespace +2. Verify the **Last Schedule** timestamp is recent and the **Last Successful** timestamp matches +3. If the next scheduled run is far away, you can trigger a manual job run from Headlamp to verify it executes without errors + +### Hooks + +For each Hook listed in your checklist: + +1. Trigger a deploy from the SleakOps Console +2. After the deploy completes, check the deployment logs in the Console to confirm each Hook ran and exited successfully (exit code 0) + +### Dependencies + +For each Dependency listed in your checklist (PostgreSQL, Redis, S3, RabbitMQ, etc.): + +1. Exercise a feature of your application that uses that dependency — for example, create a record (PostgreSQL), cache something (Redis), upload a file (S3) +2. Confirm the operation completes without errors + +--- + +## Section 2: Performance and Stress Tests + +**Applies to:** all applications exposed to real user traffic. + +The goal is to establish a performance baseline and confirm the new infrastructure handles the expected load. + +:::tip +If you have performance metrics from your previous infrastructure (response times, throughput), compare results from these tests against that baseline. +::: + +### Recommended tools + +| Tool | License | What it's good for | +| --- | --- | --- | +| [k6 ](https://k6.io/docs/) | AGPL-3.0 | Scripted load tests in JavaScript — load, stress, spike, endurance | +| [Locust ](https://docs.locust.io/) | MIT | Python-based load tests with a built-in web UI | +| [Artillery ](https://www.artillery.io/docs/) | MPL-2.0 | YAML-configured stress and spike scenarios | + +Monitor CPU, memory, requests/sec, and latency in real time using **Grafana**, available as an addon in your SleakOps Cluster. + +### Load test — verify normal traffic + +Run a test that simulates your expected normal traffic volume for at least 10 minutes. + +- **Pass:** Response time p95 is within your acceptable threshold; error rate is below 1% +- **Fail:** Latency spikes, error rate climbs, or pods restart under normal load + +### Stress test — find the breaking point + +Gradually increase load beyond your normal traffic until the system degrades. This tells you how much headroom you have. + +- **Pass:** The system degrades gracefully (slower responses, not crashes or 500 errors) +- **Fail:** Pods crash, queues overflow, or the application returns unhandled errors + +### Spike test — verify auto-scaling + +:::tip +This test only produces meaningful results if **Autoscaling (HPA)** is enabled for your Web Services. See the [Web Service docs](/docs/project/workload/webservice) to learn how to configure it. +::: + +Send a sudden burst of traffic (5–10× normal) for 2–3 minutes, then return to normal. + +- **Pass:** Karpenter and HPA scale out new pods; the spike is absorbed; the system scales back down after the burst +- **Fail:** Pods are overwhelmed before new ones come up; requests are dropped + +### Endurance test — detect memory leaks + +Run a sustained moderate load for 2–4 hours. Monitor memory usage throughout the test in **Grafana** ([install it as an addon on your Cluster](/docs/cluster/addons/grafana)) — a steady upward trend over time is the main signal of a memory leak. + +- **Pass:** Memory usage is stable; no pod restarts; response times stay consistent +- **Fail:** Memory grows steadily; pods are eventually OOM-killed; response times degrade over time + +--- + +## Section 3: Security Tests + +**Applies to:** all applications with public endpoints. + +### TLS and HTTPS + +1. Run your main domain through [SSL Labs ](https://www.ssllabs.com/ssltest/) +2. **Pass:** Grade A or A+, certificate not expiring in the next 30 days, full chain valid +3. **Fail:** Grade B or lower, expired or near-expiring certificate, broken chain + +### HTTP Security Headers + +1. Run your main domain through [securityheaders.com ](https://securityheaders.com/) +2. **Pass:** Grade A — HSTS, X-Content-Type-Options, X-Frame-Options, and Content-Security-Policy are all present +3. **Fail:** Grade C or lower, or missing HSTS + +### CORS Policy + +Run the following command replacing `YOUR_DOMAIN` with your application URL: + +```bash +curl -I -H "Origin: https://evil-site.example.com" https://YOUR_DOMAIN/api/ +``` + +- **Pass:** The response does not include `Access-Control-Allow-Origin: https://evil-site.example.com` +- **Fail:** The response reflects the origin back — your CORS policy is too permissive + +### Rate Limiting + +If your application has rate limiting configured, verify it's working: + +```bash +for i in {1..100}; do curl -s -o /dev/null -w "%{http_code}\n" https://YOUR_DOMAIN/login; done +``` + +- **Pass:** After N requests, responses start returning `429 Too Many Requests` +- **Fail:** All 100 requests return `200` — rate limiting is not active + +### Sensitive Routes + +Verify that common sensitive paths are not publicly accessible: + +```bash +curl -I https://YOUR_DOMAIN/.env +curl -I https://YOUR_DOMAIN/admin/ +curl -I https://YOUR_DOMAIN/.git/config +``` + +- **Pass:** All return `404` or `403` +- **Fail:** Any returns `200` — those files are publicly exposed + +### Authentication on Protected Endpoints + +Pick an API endpoint that requires authentication and test it without credentials: + +```bash +curl -I https://YOUR_DOMAIN/api/protected-resource/ +``` + +- **Pass:** Returns `401 Unauthorized` or `403 Forbidden` +- **Fail:** Returns `200` — the endpoint is unauthenticated + +### Dependency Audit + +Run a vulnerability scan on your application's dependencies: + +```bash +# Node.js +npm audit --audit-level=high + +# Python +pip-audit +``` + +- **Pass:** No high or critical vulnerabilities +- **Fail:** High or critical CVEs found — review and update the affected packages before going to production + +:::info +For a deeper automated scan, tools like [OWASP ZAP ](https://www.zaproxy.org/docs/) (DAST) and [Trivy ](https://trivy.dev/latest/docs/) (container/dependency scanning) can provide more coverage. +::: + +--- + +## Section 4: Infrastructure Resilience + +### 4a — Application Without Cache + +**Applies to:** applications that use Redis for caching, sessions, or rate limiting. + +The goal is to confirm your application degrades gracefully when Redis is unavailable, rather than going down completely. + +1. In the SleakOps Console, go to **Var Groups** and temporarily change your Redis connection URL to an unreachable host (for example, `redis://invalid-host:6379`) +2. Trigger a deploy — the application will start up pointing to a non-existent Redis +3. Walk through your application's main flows +4. Note which features fail or degrade — this is expected behavior, not a pass/fail in itself +5. **Pass:** The application returns controlled error messages or falls back gracefully; it does not throw unhandled 500 errors or crash +6. **Fail:** The entire application becomes unavailable, or unhandled exceptions are exposed to users +7. Revert the Var Group to the original Redis URL, trigger another deploy, and verify the application recovers normally + +:::info +Also monitor database load in Grafana during this test. If Redis caches queries, removing it may spike DB connections — verify the database can absorb the additional load. +::: + +### 4b — Spot Node Interruption + +**Applies to:** environments where any workload runs on a Spot Node Pool. + +AWS can reclaim Spot instances at any time with a 2-minute warning. This test verifies that Karpenter reschedules your workloads correctly and that no requests are lost during the transition. + +1. Open the [AWS Fault Injection Service (FIS) console ](https://console.aws.amazon.com/fis/home) +2. Create a new experiment template with the action **`aws:ec2:send-spot-instance-interruptions`** +3. Set the target to the Spot instances in your EKS cluster's Spot node group +4. Start the experiment — AWS sends the 2-minute interruption notice to the targeted instance +5. In [Headlamp ](https://headlamp.dev/) (available as an addon in your Cluster), watch the affected pods be rescheduled onto on-demand nodes +6. Monitor the error rate in Grafana during the interruption — it should stay within your SLA threshold +7. **Pass:** Pods are rescheduled within 5 minutes; error rate stays below your threshold; no manual intervention needed +8. **Fail:** Pods are stuck in `Pending`, error rate spikes and doesn't recover, or the application requires a manual restart + +Reference: [AWS FIS — Spot Instance Interruptions ](https://docs.aws.amazon.com/fis/latest/userguide/actions-reference.html) + +### 4c — Worker Resilience + +**Applies to:** applications with background Workers. + +#### Scenario 1: Poison pill (malformed task) + +A poison pill is a task that cannot be processed — malformed data, a missing required field, or an invalid reference. It's one of the most common real-world worker failure modes. + +:::info +This scenario is specific to your application's worker framework. The exact behavior (retries, DLQ routing, error logging) depends on how your application handles errors in its task processing stack (Celery, Sidekiq, BullMQ, etc.). Review your framework's documentation for how to configure these behaviors before running this test. +::: + +1. Identify a task type that your application's workers process +2. Submit that task with intentionally invalid or malformed input (missing required field, invalid ID, corrupt payload) +3. **Pass:** The worker logs the error, moves the task to the Dead Letter Queue (DLQ) after the configured retries, and continues processing other tasks normally +4. **Fail:** The worker crashes, stops processing all tasks, or silently discards the error without routing to DLQ + +#### Scenario 2: Queue saturation + +Verifies that no tasks are lost under high load and that auto-scaling works as expected. + +1. Submit a burst of tasks — aim for 5–10× the typical volume +2. Monitor queue depth in Grafana or your message broker's management UI (RabbitMQ, SQS, etc.) +3. If KEDA is configured for your workers ([see KEDA addon docs](/docs/cluster/addons/keda)), watch it scale out additional worker pods automatically as the queue grows +4. Wait for all tasks to complete and verify total processed count matches total submitted count +5. **Pass:** All tasks are eventually processed; none are lost; queue depth returns to zero +6. **Fail:** Tasks are dropped, the queue grows indefinitely, or worker pods crash under load + +### 4d — External Dependencies + +#### PostgreSQL (RDS) + +If your RDS instance is configured as Multi-AZ: + +1. From the AWS RDS console, initiate a **Reboot with failover** on your DB instance +2. Monitor your application — it should reconnect automatically within 30–60 seconds +3. **Pass:** Application reconnects without a restart; no data loss; users may see a brief error during the failover window +4. **Fail:** Application requires a manual restart to reconnect, or data corruption occurs + +#### Amazon S3 + +1. From your application, upload a test file to S3 +2. Read the file back and verify its contents +3. Delete the test file +4. **Pass:** All three operations succeed with the permissions configured in SleakOps +5. **Fail:** Any operation fails — check IAM Role for Service Account (IRSA) configuration in SleakOps + +#### Redis + +1. In the SleakOps Console, go to **Var Groups** and temporarily change your Redis connection URL to an unreachable host +2. Trigger a deploy — the application will be unable to reach Redis +3. Revert the Var Group to the original URL and deploy again +4. **Pass:** The application reconnects to Redis automatically without needing a manual restart +5. **Fail:** The application requires a restart to reconnect to Redis + +#### Third-Party APIs + +For each external API your application integrates with: + +1. Temporarily block the API domain at the network level, or use a mock that returns errors +2. Trigger the application flow that calls the API +3. **Pass:** The application handles the failure gracefully — shows a user-friendly error message, uses a fallback, or queues the request for retry +4. **Fail:** The error from the external API propagates as an unhandled 500 to the user + +--- + +## Section 5: Horizontal Scaling + +**Applies to:** applications where multiple replicas are expected to run simultaneously. + +### Multi-replica behavior + +1. Scale your main Web Service to 3 replicas from the SleakOps Console +2. Send a series of requests and verify all replicas handle them correctly (check logs in Headlamp — you should see requests distributed across pod names) +3. **Pass:** All replicas serve requests correctly; no errors related to shared state +4. **Fail:** Errors appear when a request lands on a different replica than the one that initiated a session (sticky-session issue) — the root cause is session state kept in the Pod's memory instead of a shared backend; [sticky sessions](/tutorial/sticky-sessions) can mitigate it while you externalize that state + +### Shared state between replicas + +If your application stores state in memory (user sessions, uploaded files, locks), verify that state is stored in a shared backend — not in the pod's local memory. + +1. Start a session on your application (for example, log in) +2. Scale down the pod that handled your request (use Headlamp to identify which pod) +3. Make another request — a different pod should now handle it +4. **Pass:** The session is intact; the new pod can read state from Redis/DB +5. **Fail:** Session is lost; you are logged out or get an error + +### Auto-scaling under load + +If HPA or KEDA is configured for your workloads: + +1. Run a load test (see Section 2) and watch pod count in Headlamp +2. **Pass:** New pods are created as load increases and terminated as it decreases; the application handles the transition without errors +3. **Fail:** Pods are not created in time and the application gets overwhelmed, or new pods fail their readiness probes + +--- + +## Section 6: Observability and Alerts + +**Applies to:** all applications in production. + +Observability is not optional — if something goes wrong after the migration, you need to be able to detect and diagnose it quickly. + +### Logs + +1. Perform an action in your application that generates a log entry (for example, log in, trigger an error) +2. Open **Loki** (available as an addon in your Cluster) and search for your application's logs +3. **Pass:** The log entry appears in Loki within a few seconds +4. **Fail:** No logs appear — check that your application writes to stdout/stderr, not to a file inside the container + +### Metrics in Grafana + +1. Open **Grafana** (available as an addon in your Cluster) +2. Verify that dashboards exist for your application showing at minimum: CPU usage and memory usage +3. **Pass:** All metrics are populated with recent data +4. **Fail:** Metrics are missing or show "No data" — check that Prometheus is scraping your application's metrics endpoint + +### Error visibility + +1. Intentionally trigger a 500 error in your application (for example, call an endpoint with invalid parameters that causes an unhandled exception) +2. Verify the error appears in your error tracking tool (Grafana, Loki, Sentry, CloudWatch, etc.) +3. **Pass:** The error is visible within 1–2 minutes with enough context to diagnose (stack trace, request parameters) +4. **Fail:** The error is silent — no visibility into what went wrong + +--- + +## Section 7: Deploy and Rollback + +**Applies to:** all applications. + +The deploy and rollback cycle is one of the most critical things to validate before relying on a new environment. + +### Zero-downtime deploy + +:::warning +For zero-downtime deployments to work correctly, your Web Services must have **readiness probes** and **`terminationGracePeriod`** properly configured. Kubernetes uses the readiness probe to know when a new pod is ready to receive traffic, and the termination grace period to allow in-flight requests to complete before the old pod is stopped. See the [Web Service docs](/docs/project/workload/webservice) for how to configure these. +::: + +1. While sending continuous traffic to your application (you can use a simple `watch curl` or a light load test), trigger a new deploy from the SleakOps Console +2. Monitor the error rate during the deploy +3. **Pass:** Error rate stays at 0% (or within acceptable bounds) throughout the entire deploy; no requests are dropped +4. **Fail:** Error rate spikes during the deploy — verify that readiness probes and termination grace periods are correctly set on your workloads + +### Variable group update + +1. Make a small change to one of your Var Groups (for example, change a non-critical environment variable) +2. Trigger a deploy +3. After the deploy, verify in your application or logs that the new value is active +4. **Pass:** The new value is applied without issues +5. **Fail:** The application still uses the old value, or the deploy fails due to the change + +### Rollback test + +This is the most important test in this section. Verify you can recover from a bad deploy before you need to. + +1. Note the current version of your application +2. Deploy a new version (even a trivial change — a log message, a comment) +3. From the SleakOps Console, roll back to the previous version +4. Verify that the application is running the previous version and that it works correctly (run the functional tests from Section 1) +5. **Pass:** Rollback completes within minutes; previous version is fully functional +6. **Fail:** Rollback fails, takes too long, or the previous version doesn't work after rollback + +### Database migrations (if applicable) + +If your application runs database migrations as part of the deploy: + +1. Verify that the latest migration ran successfully by checking the deploy logs in the Console +2. Verify that the migration is backward-compatible — if you needed to roll back the application, the previous version should still work with the current database schema +3. **Pass:** Migration ran successfully and is backward-compatible +4. **Fail:** Migration failed, or rolling back the app would break with the new schema + +--- + +## Tools Reference + +| Category | Tool | License | Docs | +| --- | --- | --- | --- | +| Load testing | [k6 ](https://k6.io/docs/) | AGPL-3.0 | https://k6.io/docs/ | +| Load testing | [Locust ](https://docs.locust.io/) | MIT | https://docs.locust.io/ | +| Load testing | [Artillery ](https://www.artillery.io/docs/) | MPL-2.0 | https://www.artillery.io/docs/ | +| TLS audit | [SSL Labs ](https://www.ssllabs.com/ssltest/) | Free (online) | https://www.ssllabs.com/ssltest/ | +| Security headers | [securityheaders.com ](https://securityheaders.com/) | Free (online) | https://securityheaders.com/ | +| DAST scanner | [OWASP ZAP ](https://www.zaproxy.org/docs/) | Apache-2.0 | https://www.zaproxy.org/docs/ | +| Container/dep scan | [Trivy ](https://trivy.dev/latest/docs/) | Apache-2.0 | https://trivy.dev/latest/docs/ | +| Dependency audit | `npm audit` | Built-in | https://docs.npmjs.com/cli/v10/commands/npm-audit | +| Dependency audit | [pip-audit ](https://pypi.org/project/pip-audit/) | Apache-2.0 | https://pypi.org/project/pip-audit/ | +| Chaos (Spot) | [AWS FIS ](https://docs.aws.amazon.com/fis/latest/userguide/) | Managed (free tier) | https://docs.aws.amazon.com/fis/latest/userguide/ | +| Cluster UI | [Headlamp ](https://headlamp.dev/) | Apache-2.0 | SleakOps addon | +| Metrics | Grafana | AGPL-3.0 | SleakOps addon | +| Logs | Loki | AGPL-3.0 | SleakOps addon | +| Metrics | Prometheus | Apache-2.0 | SleakOps addon | diff --git a/content/tutorials/en/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas.mdx b/content/tutorials/en/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas.mdx index eff6733d4b..72fc4d5028 100644 --- a/content/tutorials/en/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas.mdx +++ b/content/tutorials/en/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas.mdx @@ -22,9 +22,9 @@ Connect your AWS VPC to MongoDB Atlas using VPC Peering for private, low-latency ## Prerequisites -- A MongoDB Atlas account with a cluster at tier \*\*M10 or higher\*\* +- A MongoDB Atlas account with a cluster at tier **M10 or higher** - An AWS account with a VPC where your workloads run -- \*\*Project Owner\*\* role in MongoDB Atlas +- **Project Owner** role in MongoDB Atlas - DNS hostnames and DNS resolution enabled on your AWS VPC @@ -37,18 +37,18 @@ Connect your AWS VPC to MongoDB Atlas using VPC Peering for private, low-latency VPC Peering is the right choice when: -- Your workloads run inside an AWS VPC in the \*\*same region\*\* as your Atlas cluster -- You need \*\*private connectivity\*\* — traffic never leaves the AWS backbone -- You're using Atlas clusters at tier \*\*M10 or higher\*\* +- Your workloads run inside an AWS VPC in the **same region** as your Atlas cluster +- You need **private connectivity** — traffic never leaves the AWS backbone +- You're using Atlas clusters at tier **M10 or higher** - Your resources run on EKS, EC2, or any service inside the VPC -VPC Peering is \*\*not available\*\* in these cases: +VPC Peering is **not available** in these cases: -- Cluster tiers \*\*M0, M2, M5, or Serverless\*\* — these don't support peering -- \*\*Multi-cloud peering\*\* — Atlas doesn't support peering between different providers (e.g. GCP and AWS) -- \*\*Overlapping CIDRs\*\* — if your AWS VPC CIDR overlaps with Atlas's CIDR, peering can't be established +- Cluster tiers **M0, M2, M5, or Serverless** — these don't support peering +- **Multi-cloud peering** — Atlas doesn't support peering between different providers (e.g. GCP and AWS) +- **Overlapping CIDRs** — if your AWS VPC CIDR overlaps with Atlas's CIDR, peering can't be established :::warning @@ -59,12 +59,12 @@ If any of the above applies to you, skip to [Alternative: Whitelist your NAT Gat ### Alternative: Whitelist your NAT Gateway IP -If peering isn't an option, you can allow Atlas connections from your VPC by whitelisting the public IP of your \*\*NAT Gateway\*\*: +If peering isn't an option, you can allow Atlas connections from your VPC by whitelisting the public IP of your **NAT Gateway**: -1. In the AWS Console, go to \*\*VPC → NAT Gateways\*\* and copy the \*\*Elastic IP\*\* associated with your NAT Gateway. -2. In MongoDB Atlas, go to \*\*Network Access → IP Access List → Add IP Address\*\*. -3. Enter the Elastic IP with a description like \`NAT Gateway - production\`. +1. In the AWS Console, go to **VPC → NAT Gateways** and copy the **Elastic IP** associated with your NAT Gateway. +2. In MongoDB Atlas, go to **Network Access → IP Access List → Add IP Address**. +3. Enter the Elastic IP with a description like `NAT Gateway - production`. Your workloads connect to Atlas via the internet through the NAT — no peering required. @@ -84,28 +84,26 @@ This approach has higher latency than peering but works with any cluster tier an You'll need the following values from your AWS account before configuring the peering connection in Atlas. -\*\*Get your Account ID\*\* +**Get your Account ID** -Click your username in the top-right corner of the AWS Console. Your 12-digit \*\*Account ID\*\* appears in the dropdown. +Click your username in the top-right corner of the AWS Console. Your 12-digit **Account ID** appears in the dropdown. +{/* TODO: screenshot - AWS Console top-right dropdown showing Account ID */} +**Get your VPC ID and CIDR** -\*\*Get your VPC ID and CIDR\*\* +In the AWS Console, search for **VPC** and open **Your VPCs**. Select the VPC where your workloads run and note the **VPC ID** (starts with `vpc-`) and the **IPv4 CIDR** (e.g. `10.0.0.0/16`). +{/* TODO: screenshot - AWS Console VPC list showing VPC ID and IPv4 CIDR columns */} -In the AWS Console, search for \*\*VPC\*\* and open \*\*Your VPCs\*\*. Select the VPC where your workloads run and note the \*\*VPC ID\*\* (starts with \`vpc-\`) and the \*\*IPv4 CIDR\*\* (e.g. \`10.0.0.0/16\`). - - - - -| \*\*Field\*\* | \*\*Where to find it\*\* | +| **Field** | **Where to find it** | | -------------------------- | ------------------------------------------------- | -| \*\*Account ID\*\* | Top-right dropdown in the AWS Console | -| \*\*VPC ID\*\* | VPC → Your VPCs (starts with \`vpc-\`) | -| \*\*VPC CIDR\*\* | VPC → Your VPCs → IPv4 CIDR column | -| \*\*Application VPC Region\*\* | The AWS region where your VPC lives | +| **Account ID** | Top-right dropdown in the AWS Console | +| **VPC ID** | VPC → Your VPCs (starts with `vpc-`) | +| **VPC CIDR** | VPC → Your VPCs → IPv4 CIDR column | +| **Application VPC Region** | The AWS region where your VPC lives | --- @@ -114,29 +112,41 @@ In the AWS Console, search for \*\*VPC\*\* and open \*\*Your VPCs\*\*. Select th ### Step 2 — Create the Peering Connection in Atlas -1. In MongoDB Atlas, go to \*\*Network Access\*\* in the left sidebar. -2. Click the \*\*Peering\*\* tab, then \*\*Add Peering Connection\*\*. - - - +1. In MongoDB Atlas, go to **Network Access** in the left sidebar. +2. Click the **Peering** tab, then **Add Peering Connection**. -3. Select \*\*AWS\*\* as the cloud provider and fill in the form with the values from Step 1: - - \*\*Account ID\*\* — your 12-digit AWS account number - - \*\*VPC ID\*\* — the VPC ID starting with \`vpc-\` - - \*\*VPC CIDR\*\* — your VPC's IP range - - \*\*Application VPC Region\*\* — the AWS region - - \*\*Atlas VPC CIDR\*\* — Atlas will suggest a range (e.g. \`192.168.240.0/21\`); keep it unless it conflicts with your network + + MongoDB Atlas Network Access Peering tab + +3. Select **AWS** as the cloud provider and fill in the form with the values from Step 1: + - **Account ID** — your 12-digit AWS account number + - **VPC ID** — the VPC ID starting with `vpc-` + - **VPC CIDR** — your VPC's IP range + - **Application VPC Region** — the AWS region + - **Atlas VPC CIDR** — Atlas will suggest a range (e.g. `192.168.240.0/21`); keep it unless it conflicts with your network + + MongoDB Atlas peering form with AWS account details + - -4. Click \*\*Initiate Peering\*\*. - - -Atlas will show the connection with status \*\*"Waiting for Approval"\*\*. The request must now be accepted from the AWS Console. +4. Click **Initiate Peering**. +Atlas will show the connection with status **"Waiting for Approval"**. The request must now be accepted from the AWS Console. + + MongoDB Atlas peering connection waiting for approval + --- @@ -144,22 +154,55 @@ Atlas will show the connection with status \*\*"Waiting for Approval"\*\*. The r ### Step 3 — Accept the Peering Request in AWS -1. In the AWS Console, go to \*\*VPC → Peering connections\*\*. -2. You'll see a connection with status \*\*"Pending acceptance"\*\*. +1. In the AWS Console, go to **VPC → Peering connections**. +2. You'll see a connection with status **"Pending acceptance"**. + + AWS VPC Peering connections list with pending request + + + AWS VPC Peering pending request details + - -3. Select the connection, click \*\*Actions → Accept request\*\*. +3. Select the connection, click **Actions → Accept request**. 4. Review the details in the modal (VPCs, CIDRs, regions) and confirm. - - - -Once accepted, the connection status changes to \*\*"Active"\*\* in AWS and \*\*"Available"\*\* in Atlas. - - - + + AWS Accept VPC peering request dialog + + + + AWS VPC peering request accepted confirmation + + +Once accepted, the connection status changes to **"Active"** in AWS and **"Available"** in Atlas. + + + MongoDB Atlas peering connection status Available + + + + MongoDB Atlas peering connection Available status confirmation + --- @@ -170,15 +213,26 @@ Once accepted, the connection status changes to \*\*"Active"\*\* in AWS and \*\* For traffic to flow through the peering connection, you need to add a route to the Route Table of the subnets where your workloads run. -1. In the AWS Console, go to \*\*VPC → Route Tables\*\*. +1. In the AWS Console, go to **VPC → Route Tables**. 2. Select the Route Table associated with your workload subnets. -3. Open the \*\*Routes\*\* tab and click \*\*Edit routes → Add route\*\*: - - \*\*Destination\*\*: the Atlas VPC CIDR (e.g. \`192.168.240.0/21\`) - - \*\*Target\*\*: select \*\*Peering Connection\*\* and choose the connection you just created -4. Click \*\*Save changes\*\*. - - - +3. Open the **Routes** tab and click **Edit routes → Add route**: + - **Destination**: the Atlas VPC CIDR (e.g. `192.168.240.0/21`) + - **Target**: select **Peering Connection** and choose the connection you just created +4. Click **Save changes**. + + + AWS Route Tables list + + + + AWS Route Table with Atlas peering route added + --- @@ -189,25 +243,25 @@ For traffic to flow through the peering connection, you need to add a route to t Create a Security Group that allows outbound traffic to MongoDB Atlas ports: -1. In the AWS Console, go to \*\*EC2 → Security Groups → Create security group\*\*. -2. Add an \*\*outbound rule\*\*: +1. In the AWS Console, go to **EC2 → Security Groups → Create security group**. +2. Add an **outbound rule**: -| \*\*Type\*\* | \*\*Protocol\*\* | \*\*Port range\*\* | \*\*Destination\*\* | +| **Type** | **Protocol** | **Port range** | **Destination** | | ---------- | ------------ | -------------- | ---------------------------------------- | -| Custom TCP | TCP | 27015 – 27017 | Atlas VPC CIDR (e.g. \`192.168.240.0/21\`) | +| Custom TCP | TCP | 27015 – 27017 | Atlas VPC CIDR (e.g. `192.168.240.0/21`) | 3. Attach this Security Group to the EC2 instances, EKS node groups, or other resources that need to connect to Atlas. :::tip -If you're using \*\*EKS with Karpenter\*\*, add the following tag to the Security Group so Karpenter discovers and applies it automatically: +If you're using **EKS with Karpenter**, add the following tag to the Security Group so Karpenter discovers and applies it automatically: -| \*\*Key\*\* | \*\*Value\*\* | -| ------------------------ | ---------------- | -| \`karpenter.sh/discovery\` | \`YOUR_CLUSTER_NAME\` | +| **Key** | **Value** | +| -------------------------- | --------------------- | +| `karpenter.sh/discovery` | `YOUR_CLUSTER_NAME` | ::: @@ -220,10 +274,9 @@ If you're using \*\*EKS with Karpenter\*\*, add the following tag to the Securit Creating the peering connection alone is not enough — you also need to allow access at the network level. -In MongoDB Atlas, go to \*\*Network Access → IP Access List → Add IP Address\*\* and enter your \*\*AWS VPC CIDR\*\* (e.g. \`10.0.0.0/16\`). - - +In MongoDB Atlas, go to **Network Access → IP Access List → Add IP Address** and enter your **AWS VPC CIDR** (e.g. `10.0.0.0/16`). +{/* TODO: screenshot - MongoDB Atlas IP Access List with VPC CIDR added */} --- @@ -234,29 +287,55 @@ In MongoDB Atlas, go to \*\*Network Access → IP Access List → Add IP Address If your team accesses MongoDB Atlas through a VPN like Pritunl, standard DNS resolution won't work over peering by default. Follow these steps to enable it: -\*\*Enable Custom DNS in Atlas\*\* - +**Enable Custom DNS in Atlas** -In Atlas, go to \*\*Project → Settings\*\* and enable \*\*"Using Custom DNS on AWS with VPC peering"\*\*. +In Atlas, go to **Project → Settings** and enable **"Using Custom DNS on AWS with VPC peering"**. + + MongoDB Atlas Project Settings with Custom DNS for VPC peering enabled + +**Use the Private Peering connection string** -\*\*Use the Private Peering connection string\*\* +When connecting to your cluster, select **"Private IP for Peering"** in the connection modal. This provides a hostname that resolves to the cluster's private IP. -When connecting to your cluster, select \*\*"Private IP for Peering"\*\* in the connection modal. This provides a hostname that resolves to the cluster's private IP. + + MongoDB Atlas connection modal showing Private IP for Peering option + + + MongoDB Atlas private peering connection string + - - -\*\*Add the Atlas CIDR route to Pritunl\*\* +**Add the Atlas CIDR route to Pritunl** In your Pritunl server settings, add the Atlas VPC CIDR as an additional route so VPN clients can reach it. + + Pritunl server settings showing Atlas CIDR route configuration + - + + Pritunl server with Atlas CIDR route saved + Connect to the VPN and test the connection using the new private address. @@ -267,19 +346,19 @@ Connect to the VPN and test the connection using the new private address. ## Verification -\*\*From a private EC2 instance:\*\* +**From a private EC2 instance:** -\`\`\`bash +```bash dnf install -qy mongodb-mongosh-shared-openssl3 mongosh "mongodb+srv://YOUR_CLUSTER_URL" --apiVersion 1 --username YOUR_USERNAME -\`\`\` +``` -\*\*From a Pod in EKS:\*\* +**From a Pod in EKS:** -\`\`\`yaml +```yaml apiVersion: v1 kind: Pod metadata: @@ -289,13 +368,13 @@ spec: - name: mongodb-client image: mongo:latest command: ["/bin/sh", "-c", "sleep 3600"] -\`\`\` +``` -\`\`\`bash +```bash kubectl exec -it mongodb-client -- \ mongosh "mongodb+srv://YOUR_CLUSTER_URL" --apiVersion 1 --username YOUR_USERNAME -\`\`\` +``` A successful connection confirms peering is working correctly. diff --git a/content/tutorials/en/install-datadog.mdx b/content/tutorials/en/install-datadog.mdx index aaae174dc5..6521ca297d 100644 --- a/content/tutorials/en/install-datadog.mdx +++ b/content/tutorials/en/install-datadog.mdx @@ -1,7 +1,7 @@ --- title: Install Datadog on a SleakOps EKS Cluster sidebar_label: Install Datadog -sidebar_position: 34 +sidebar_position: 33 description: Install the Datadog monitoring agent on an Amazon EKS cluster managed by SleakOps using Helm, with a values.yaml and recommended best practices. tags: - kubernetes @@ -17,6 +17,20 @@ import { FiExternalLink } from "react-icons/fi"; Install the [Datadog ](https://www.datadoghq.com/) monitoring agent on a SleakOps EKS cluster using Helm to gain full visibility into application performance and infrastructure health. +## Helm vs. Datadog Operator — which guide is right for you? + +SleakOps has two tutorials for installing Datadog. They cover different approaches and are **not combined** — choose one based on your needs: + +| | **This guide (Helm)** | **[Datadog Operator](/tutorial/deploy-datadog-operator)** | +|---|---|---| +| **Setup complexity** | Low | High | +| **Lifecycle management** | Manual (Helm upgrades) | Automatic (Operator manages the agent) | +| **Auto-instrumentation** | No | Yes (admission controller) | +| **Karpenter NodePool tolerations** | Manual | Built-in | +| **Best for** | Quick monitoring setup, simple clusters | Multi-workload clusters, auto-instrumentation, Karpenter | + +If you're not sure which to use, start here. + ## Prerequisites - A SleakOps EKS cluster with `kubectl` configured @@ -82,6 +96,10 @@ All `datadog-agent-*` pods should reach `Running` state within a few minutes. | **Datadog Operator** | Lifecycle management, CRD-based | More complex to set up | | **Fargate Logging** | No node management | Works only for specific workloads | +## Next Steps + +Need auto-instrumentation, admission controller, or Karpenter NodePool tolerations? See the [Deploy Datadog Operator](/tutorial/deploy-datadog-operator) guide for the advanced CRD-based setup. + ## Best Practices - **Secure the API key:** Store it in a Kubernetes Secret rather than directly in `values.yaml`. diff --git a/content/tutorials/en/lens-cluster-connectivity.mdx b/content/tutorials/en/lens-cluster-connectivity.mdx index 9b89d8b5ca..18725426e0 100644 --- a/content/tutorials/en/lens-cluster-connectivity.mdx +++ b/content/tutorials/en/lens-cluster-connectivity.mdx @@ -77,3 +77,7 @@ In the Pritunl connection profile, enable the **Force DNS configuration** option | DEV | `10.110.0.2` | | MGT | `10.120.0.2` | | PRD | `10.130.0.2` | + +## See also + +If the steps above don't fully resolve the DNS issue, you may need to apply the VPN DNS configuration explicitly using OS-specific scripts. See the [Universal DNS Fix for Pritunl Client](/tutorial/pritunl-dns-universal) guide. diff --git a/content/tutorials/en/migrate-rds-snapshot-between-accounts.mdx b/content/tutorials/en/migrate-rds-snapshot-between-accounts.mdx index 8e256f823d..e2d4959582 100644 --- a/content/tutorials/en/migrate-rds-snapshot-between-accounts.mdx +++ b/content/tutorials/en/migrate-rds-snapshot-between-accounts.mdx @@ -116,7 +116,8 @@ Unencrypted snapshots can be shared directly between accounts. If your RDS uses 1. Go to **SleakOps → Dependencies → Create**. 2. Select **Create an RDS from a snapshot**. -3. Enter the identifier of the copied snapshot. +3. If the snapshot isn't encrypted with the default AWS-managed key, enter the full ARN of the KMS key used for the copy in the **KMS Key ID** field (format: `arn:aws:kms:::key/`). +4. Enter the identifier of the copied snapshot. --- diff --git a/content/tutorials/en/nodepool-strategies.mdx b/content/tutorials/en/nodepool-strategies.mdx index f144aaba34..6ea7e6749d 100644 --- a/content/tutorials/en/nodepool-strategies.mdx +++ b/content/tutorials/en/nodepool-strategies.mdx @@ -20,9 +20,13 @@ Learn how to configure nodepools in SleakOps to optimize costs, improve performa ## What Is a nodepool? -In SleakOps, a **nodepool** is a group of EC2 nodes within your Kubernetes cluster that share the same configuration — architecture, instance type, billing model, and resource limits. Karpenter manages autoscaling within each pool automatically. +In SleakOps, a **nodepool** is not a group of EC2 machines that are already running: it's the **definition** of a group of EC2 nodes that Karpenter can provision on demand. Each nodepool specifies which nodes can be created — architecture, instance type, billing model, and resource limits — and Karpenter launches and removes nodes matching that definition automatically based on load, even scaling to zero when there are no workloads. -When you create a Cluster, SleakOps provisions a set of default nodepools: +:::tip +Don't confuse the nodepool with the EC2 instances themselves. The nodepool is the **template**; the actual EC2 nodes come and go on demand. +::: + +When you create a Cluster, SleakOps configures a set of default nodepools: | **nodepool** | **Purpose** | |---|---| @@ -37,6 +41,8 @@ Each Project Environment is assigned to one nodepool. The assignment can be chan ## Cost Optimization Strategies +Not sure yet where your spend is actually going? Start with the [Cost Review Guide](/tutorial/cost-review-guide) to read your current costs before applying any of these strategies. + ### 1. Spot with On-Demand Fallback The most effective way to reduce compute costs is to run workloads on **Spot instances** while keeping **On-Demand as an automatic fallback**. In SleakOps, configure this by selecting both `Spot` and `On-Demand` as Node Types when creating or editing a nodepool. The system prioritizes them in this order: **Reserved → Spot → On-Demand**. @@ -59,6 +65,18 @@ To use ARM in SleakOps, three conditions must be met: **Best for:** services written in Go, Python, or Node.js without native x86-only dependencies. +### 3. Cost Segmentation per Project + +A dedicated nodepool per Project is an organizational strategy where each Project Environment runs in its own isolated compute pool. Resource limits, instance types, and billing models are configured independently for each project. + +**Advantage:** fine-grained control. Each project has its own compute boundary — there is no resource contention between projects, and you can tune settings precisely for each workload profile. + +**Disadvantage:** nodes cannot be shared across projects. When one project's pool is underutilized, that spare capacity is not available to other projects, resulting in higher overall infrastructure costs compared to a shared pool approach. + +:::tip +This pattern is best suited to scenarios where strict isolation is a business or compliance requirement, or when projects have significantly different resource profiles. For most workloads, a smaller set of shared pools delivers better cost efficiency. +::: + --- ## Performance Strategies diff --git a/content/tutorials/en/optimize-aws-costs.mdx b/content/tutorials/en/optimize-aws-costs.mdx index c2c7226c27..1774b6f88b 100644 --- a/content/tutorials/en/optimize-aws-costs.mdx +++ b/content/tutorials/en/optimize-aws-costs.mdx @@ -15,6 +15,8 @@ import { FiExternalLink } from "react-icons/fi"; Practical techniques to reduce AWS costs without sacrificing reliability — covering compute, storage, CDN, and right-sizing strategies. +Haven't looked at where your spend is actually going yet? Start with the [Cost Review Guide](/tutorial/cost-review-guide) to read your Cost Explorer and Kubecost dashboards first. + ## 1. Spot Instances with Auto Scaling — Cut EC2 Costs Significantly Running all workloads on On-Demand EC2 instances is expensive. Moving stateless or fault-tolerant workloads to **Spot Instances** backed by an **Auto Scaling Group (ASG)** with On-Demand fallback can cut those costs substantially. diff --git a/content/tutorials/en/pritunl-dns-universal.mdx b/content/tutorials/en/pritunl-dns-universal.mdx index b1416e7090..c152924676 100644 --- a/content/tutorials/en/pritunl-dns-universal.mdx +++ b/content/tutorials/en/pritunl-dns-universal.mdx @@ -243,3 +243,7 @@ chmod +x universal_fix_vpn_dns.sh :::warning These scripts do **not** make permanent changes to the system. DNS configuration is removed automatically when the VPN disconnects. ::: + +## See also + +If you're troubleshooting Lens specifically (unable to connect to a SleakOps cluster), see the [Troubleshoot Cluster Connectivity with Lens](/tutorial/lens-cluster-connectivity) guide for VPN checks and Lens-specific steps. diff --git a/content/tutorials/en/rds-external-access.mdx b/content/tutorials/en/rds-external-access.mdx new file mode 100644 index 0000000000..483ab5675d --- /dev/null +++ b/content/tutorials/en/rds-external-access.mdx @@ -0,0 +1,35 @@ +--- +title: Find Your Public RDS Endpoint +sidebar_label: RDS Public Endpoint +sidebar_position: 21 +description: Locate the connection endpoint of a public RDS read replica from the AWS Console. +tags: + - aws + - rds + - database + - networking +--- + +import { FiExternalLink } from "react-icons/fi"; + +Once SleakOps has configured a public read replica for your RDS instance, you can find its connection endpoint directly in the AWS Console. + +## Finding the Endpoint + +1. Open the [AWS Console ](https://console.aws.amazon.com/) and navigate to **RDS**. +2. In the left sidebar, click **Databases**. +3. Find and click on your DB instance or read replica. Public replicas are typically named with a `-replica` or similar suffix. +4. Open the **Connectivity & security** tab. +5. Copy the **Endpoint** value — this is the hostname your application or client will connect to. + +The endpoint follows the standard AWS RDS format: + +``` +..rds.amazonaws.com +``` + +Use it along with the port for your engine (default `5432` for PostgreSQL, `3306` for MySQL and MariaDB, `1521` for Oracle, `1433` for SQL Server; Aurora uses `5432` or `3306` depending on the compatible engine) to configure your database client or connection string. + +:::warning +Public RDS instances are reachable from the internet. Always verify that the associated Security Group restricts inbound access to only the IP ranges that need it. +::: diff --git a/content/tutorials/en/sticky-sessions.mdx b/content/tutorials/en/sticky-sessions.mdx new file mode 100644 index 0000000000..b626d9d4fe --- /dev/null +++ b/content/tutorials/en/sticky-sessions.mdx @@ -0,0 +1,146 @@ +--- +title: Configure Sticky Sessions +sidebar_label: Sticky Sessions +sidebar_position: 49 +description: Pin each client to the same Web Service replica by enabling ALB cookie stickiness from the ingress annotations. +tags: + - networking + - kubernetes + - aws + - scaling + - performance +image: /img/tutorials/sticky-sessions/connection-settings-advanced.png +--- + +import Zoom from "react-medium-image-zoom"; +import "react-medium-image-zoom/dist/styles.css"; +import { FiExternalLink } from "react-icons/fi"; + +Pin each client to the same Web Service replica by enabling ALB cookie stickiness from the ingress annotations. + +## When you need sticky sessions (and when you don't) + +Every Web Service with more than one replica is load balanced across its Pods, so consecutive requests from the same browser can land on different Pods. If your application keeps session state in memory — a login session, a shopping cart, an upload in progress — those requests break. + +Stickiness makes the load balancer send a client back to the Pod it used before. It is a useful stopgap, but it is not a fix for in-memory state: + +- The affinity dies with the Pod. Every deploy replaces all Pods, and every scale-in removes some, so sticky clients get reassigned and lose their session anyway. +- One Pod can end up with a disproportionate share of long-lived clients, which works against autoscaling. + +The durable fix is to move session state to a shared backend — a [Redis Dependency](/docs/project/dependency/redis-aws) or your database — so any replica can serve any request. The [Environment testing guide](/tutorial/environment-exhaustive-testing-guide) includes a test for exactly this failure. Reach for stickiness when you cannot change the application, or as a bridge while you externalize the session store. + +## Prerequisites + +- Account in SleakOps +- A Cluster configured ([Cluster docs](/docs/cluster)) +- An Environment configured ([Environment docs](/docs/environment)) +- A Web Service with the `public` or `private` service schema. `internal` services have no Ingress, so stickiness does not apply to them. +- A role other than **Viewer** — Viewers cannot edit a Workload's configuration. + +## Let's Start + +SleakOps exposes Web Services through an AWS Application Load Balancer, and stickiness is a target group attribute on that load balancer. You enable it by adding one annotation to the Ingress that SleakOps generates for your Web Service. + +### Add the stickiness annotation + +1. Open your Web Service from **Workloads > Web Services**. +2. In the **Connection Settings** section, click **Edit Ingress**. +3. In the Key/Value table at the bottom of the dialog, add this pair: + +| **Field** | **Value** | +| --------- | ----------------------------------------------------------------------------------------- | +| **Key** | `alb.ingress.kubernetes.io/target-group-attributes` | +| **Value** | `stickiness.enabled=true,stickiness.type=lb_cookie,stickiness.lb_cookie.duration_seconds=86400` | + +4. Leave **Deploy?** enabled and click **Update ingress config**. The annotation only reaches the cluster on the next deploy. + + + IngressConfig dialog with the target-group-attributes annotation in the Extra Annotations table, ALB default annotations enabled and Deploy? on + + +Every other field keeps its default — you only add the annotation row. + +:::warning Leave ALB default annotations enabled +The same dialog has an **ALB default annotations** switch. Keep it on. It generates the annotations the Ingress needs to work at all — `target-type: ip`, the load balancer group name, and the health check settings. Your extra annotations are merged on top of those, so there is no reason to disable it. +::: + +The `target-type: ip` that SleakOps sets by default is also a hard requirement for ALB stickiness, and it is what makes stickiness useful here: the load balancer registers Pod IPs as targets, so the cookie pins a client to a specific Pod rather than to a Node. + +### Set it from the Web Service form + +The same field is available in the Web Service form, whether you are creating the Workload or editing it. In the **Connection Settings** step, expand the **Advanced** section and fill in **Extra Annotations** under **Ingress Annotations**. The annotation applies to every host of the Web Service — its default URL and any custom Domain pointing at it. + + + Connection Settings step of the Web Service form with the Advanced section expanded, showing the Ingress Annotations block + + +### Tune the cookie + +The annotation value is a comma-separated list of target group attributes. It replaces the whole set of stickiness attributes, so send every pair you need in a single value. + +| **Attribute** | **Description** | **Default** | +| ---------------------------------------- | ------------------------------------------------------------------------------- | ----------------- | +| **stickiness.enabled** | Turns stickiness on. `true` or `false`. | `false` | +| **stickiness.type** | `lb_cookie` for a cookie the load balancer generates, `app_cookie` to follow one your application sets. | — | +| **stickiness.lb_cookie.duration_seconds** | How long the affinity lasts with `lb_cookie`. From 1 second to 604800 (7 days). | `86400` (1 day) | +| **stickiness.app_cookie.cookie_name** | Name of your application's cookie. Required with `app_cookie`. | — | +| **stickiness.app_cookie.duration_seconds** | How long the affinity lasts with `app_cookie`. From 1 second to 604800 (7 days). | `86400` (1 day) | + +With `app_cookie`, the cookie name cannot start with `AWSALB`, `AWSALBAPP` or `AWSALBTG` — those prefixes are reserved by the load balancer. + +For example, a two-hour affinity driven by your own `JSESSIONID` cookie: + +``` +stickiness.enabled=true,stickiness.type=app_cookie,stickiness.app_cookie.cookie_name=JSESSIONID,stickiness.app_cookie.duration_seconds=7200 +``` + +See the [ALB sticky sessions documentation ](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/sticky-sessions.html) for the full behavior of each mode. + +### Verify it + +Once the deploy finishes, verify it end to end: + +**1. The load balancer sets a cookie.** Request your service and look at the response headers: + +```bash +curl -sI https://myservice.myenv.sleakops.com | grep -i set-cookie +``` + +With `lb_cookie` you get two cookies: `AWSALB`, and a second `AWSALBCORS` carrying the same information plus the `SameSite` attribute that some browsers require for cross-origin requests. The load balancer always sends both, on CORS and non-CORS responses alike. + +With `app_cookie` you also get two: the one your application sets, and `AWSALBAPP-0` generated by the load balancer. Cookies over 4 KB are sharded into further fragments — `AWSALBAPP-1` and up, to a maximum of four shards and 16 KB in total. + +If none of these appear, the annotation did not reach the Ingress — go back to step 1 and confirm the deploy completed. + +**2. The same Pod answers.** Save the cookies and replay them: + +```bash +curl -s -c cookies.txt https://myservice.myenv.sleakops.com > /dev/null +for i in $(seq 1 10); do curl -s -b cookies.txt https://myservice.myenv.sleakops.com/your-debug-path; done +``` + +If your application exposes its hostname anywhere — the `HOSTNAME` environment variable inside a Pod is the Pod name — every response should report the same one. Otherwise, open the Web Service logs in [Headlamp](/docs/cluster/addons/headlamp) and confirm that only one Pod records those requests. + +**3. The annotation is on the live object.** If either check above fails, open the Ingress for your Environment's Namespace in Headlamp and confirm that `alb.ingress.kubernetes.io/target-group-attributes` appears in its annotations with the value you set. If it is missing, the deploy did not go through; if it is there, the problem is downstream — check that your Web Service has more than one replica. + +## Limitations + +:::warning +- **Affinity does not survive Pod replacement.** Deploys, scale-in and Node consolidation all reassign sticky clients. Stickiness reduces how often a client changes Pod; it never guarantees it won't. +- **It is not a substitute for shared session state.** If losing a session is unacceptable, store it in Redis or your database. +- **The Kubernetes `sessionAffinity: ClientIP` setting has no effect here.** The load balancer sends traffic straight to Pod IPs, bypassing the Service's own load balancing, so affinity has to be configured on the load balancer. +- **`ssl-redirect` and `listen-ports` cannot be overridden** through Extra Annotations on hosts served over HTTPS — SleakOps sets those last for TLS hosts. +- **`internal` Web Services have no Ingress**, so there is nothing to annotate. +::: + +## Next Steps + +- [Web Service configuration](/docs/project/workload/webservice) — the rest of the Workload settings, including replicas and autoscaling +- [Manifests](/docs/project/manifests) — edit the generated Ingress YAML directly when an annotation is not enough +- [Values](/docs/project/values) — override any generated Helm value, including per-host ingress settings diff --git a/content/tutorials/es/amazon-ses.mdx b/content/tutorials/es/amazon-ses.mdx index ac51390d98..494a262074 100644 --- a/content/tutorials/es/amazon-ses.mdx +++ b/content/tutorials/es/amazon-ses.mdx @@ -16,9 +16,17 @@ import { FiExternalLink } from "react-icons/fi"; Configurá Amazon Simple Email Service (SES) para enviar emails desde tu aplicación, desde el modo sandbox hasta la configuración en producción. +:::info +**Amazon SES se configura por cuenta de AWS.** Si tus ambientes de SleakOps corren en varias cuentas de AWS, cada una necesita su propia configuración de SES. + +**Recomendación:** mantené tu cuenta de desarrollo en modo sandbox — si tenés un ambiente de staging, debería compartir esa misma cuenta de desarrollo. Solo tu cuenta de producción debería solicitar acceso a producción. + +Verificá el dominio propio de tu organización (ej. `miempresa.com`) en la cuenta de desarrollo para que el equipo pueda enviar emails de prueba sin afectar la reputación de envío en producción. +::: + ## Prerrequisitos -- Acceso a la consola de AWS con permisos para administrar SES +- Acceso a la cuenta de AWS donde querés configurar SES - Un dominio o dirección de email desde donde querés enviar - Si usás dominio: acceso a tu proveedor de DNS para agregar registros de verificación @@ -35,7 +43,7 @@ Todas las cuentas nuevas de SES comienzan en **modo sandbox**, que solo permite - **Domain** — verifica el dominio completo (recomendado para producción). AWS provee registros DNS (TXT/CNAME) para agregar en tu proveedor de DNS. :::tip -Verificá tu dominio de producción temprano — podés reutilizar el mismo dominio verificado cuando salgas del sandbox. +En desarrollo, verificá el dominio propio de tu organización temprano. Esto le permite a tu equipo enviar emails de prueba a cualquier dirección dentro de ese dominio sin necesidad de verificaciones individuales. ::: ### Paso 2 — Enviar un email de prueba en sandbox @@ -46,7 +54,7 @@ Usá el botón **Send test email** en la consola de SES o el AWS CLI para confir ### Paso 3 — Solicitar acceso a producción -Para enviar a cualquier destinatario, necesitás salir del modo sandbox. +Para enviar a cualquier destinatario, necesitás salir del modo sandbox. **Hacé esto únicamente en tu cuenta de producción.** **Antes de enviar la solicitud:** diff --git a/content/tutorials/es/cost-review-guide.mdx b/content/tutorials/es/cost-review-guide.mdx new file mode 100644 index 0000000000..6d1511e7b1 --- /dev/null +++ b/content/tutorials/es/cost-review-guide.mdx @@ -0,0 +1,124 @@ +--- +title: Cómo revisar tus costos en SleakOps +sidebar_label: Guía de revisión de costos +sidebar_position: 48 +description: Un recorrido práctico por el Cost Explorer de SleakOps, Kubecost y las Cost Allocation Tags — cómo leer lo que ya estás gastando antes de decidir qué optimizar. +tags: + - billing + - cost-analysis + - kubecost + - monitoring +image: /img/tutorials/cost-review-guide/cost-explorer-dashboard.png +--- + +import Zoom from "react-medium-image-zoom"; +import "react-medium-image-zoom/dist/styles.css"; +import { FiExternalLink } from "react-icons/fi"; + +Aprendé a leer tu gasto en AWS dentro de SleakOps — dónde mirar, cómo llegar al recurso puntual que está generando un costo, y qué revisar primero cuando un número no cierra. + +## Por qué revisar tus costos regularmente + +El gasto en AWS cambia a medida que cambia tu infraestructura: un ambiente nuevo, un workload que escaló, un nodepool corriendo más nodos On-Demand de lo esperado. Revisar el Cost Explorer con una frecuencia regular — semanal o al menos una vez al mes — te permite detectar esa variación cuando todavía es un número chico, en lugar de encontrarla a fin de mes. + +Esta guía cubre **cómo leer e interpretar** lo que ya estás gastando. Si buscás formas de reducir costos activamente, mirá [Estrategias de optimización de costos en AWS](/tutorial/optimize-aws-costs) y la sección [Estrategias de optimización de costos](/tutorial/nodepool-strategies#estrategias-de-optimización-de-costos) de la guía de Estrategias de Nodepools. + +--- + +## El Cost Explorer (`/billing`) + +El Cost Explorer es el lugar central para revisar el gasto en todas las cuentas de AWS conectadas a tu empresa. + +**Cómo llegar** — cualquiera de estas opciones: +- Hacé clic en **Go to Cost Explorer** en la tarjeta de costo del Dashboard principal. +- Abrí el detalle de un **Cluster**, **Project** o **Dependency** y hacé clic en su botón **Cost Explorer** — esto abre el Cost Explorer ya filtrado a ese recurso puntual. + + + Dashboard del Cost Explorer de SleakOps con las tarjetas de cuenta de AWS y el gráfico de costos agrupado por tipo de recurso + + +**Tarjetas de cuenta** — una por cada cuenta de AWS (production, development, management), cada una mostrando: +- Costo del mes actual. +- Forecast del mes (proyección del total del mes según lo gastado hasta el momento). +- Variación respecto al mes anterior. + +**Filtros:** + +| Filtro | Opciones | +|---|---| +| **Rango de fechas** | Last 7 days, Last 30 days, Last 90 days, This month, Last month, Last quarter, o un rango personalizado | +| **Agrupar por** | día, semana, mes | +| **Tipo de recurso** | Cluster, Environment, NodePool, Addon, ProjectEnv, Dependency | + +**Drill-down** — hacé clic en una barra del gráfico para bajar un nivel: cuenta → tipo de recurso → recurso individual (un cluster, dependencia o ambiente de proyecto puntual). Hacé clic en **View Resources** para abrir el listado completo y paginado de recursos detrás de la selección actual, con nombre, fecha, costo, cuenta y tipo de recurso. + + + Drill-down del Cost Explorer mostrando el listado de costos por recurso después de hacer clic en una barra del gráfico + + +**Exportar** — usá **Export CSV** para descargar el listado de recursos, o **Export PDF** para descargar un resumen que incluye el gráfico. + +--- + +## Bajando a nivel Kubernetes con Kubecost + +Los filtros de "Tipo de recurso" del Cost Explorer llegan hasta el nivel de objeto de SleakOps (cluster, ambiente de proyecto, dependencia, etc.). Para desglosar costos más allá de eso — por namespace, pod, deployment o nodo de Kubernetes — instalá el addon [Kubecost](/docs/cluster/addons/kubecost) en el cluster. + +Cuando el **Tipo de recurso** está en **Cluster** y hay un cluster seleccionado, el Cost Explorer muestra un tag de Kubecost: +- Si Kubecost ya está instalado, el tag abre su dashboard, filtrado a los detalles de costo de ese cluster. +- Si todavía no está instalado, el tag lleva al formulario de instalación del addon. + +El dashboard propio de Kubecost es donde vas a encontrar la métrica de costo `idle` — capacidad que estás pagando pero no usando — y el desglose de costos por namespace, por nodo y de storage. Mirá la [documentación de Kubecost](/docs/cluster/addons/kubecost) para saber cómo leer ese dashboard. + +--- + +## El reporte de cost optimization con IA + +Además de la revisión manual, SleakOps puede generar por vos un informe de optimización de costos usando IA. Es un buen complemento en una cadencia más larga — trimestral o semestral — cuando querés una foto consolidada con recomendaciones en lugar de recorrer los dashboards a mano. + +Para generarlo: + +1. Andá a **Settings → Reports** y hacé clic en **Create Report**. +2. En el drawer de soporte, elegí la tarjeta **"Informe de Costos"** y confirmá con **Generate Report**. +3. El informe se genera dentro de una conversación de soporte — cuando está listo, aparece en el listado de Reports. Usá **Open report** para abrirlo en una pestaña nueva; desde ahí podés imprimirlo o guardarlo como PDF. + +El informe incluye un desglose detallado de costos de AWS por servicio, tendencias de gasto de los últimos 3 meses y recomendaciones de optimización. Si buscás puntualmente right-sizing de Kubernetes, el informe **"Análisis de Overprovisioning K8s"** del mismo catálogo compara los requests de tus workloads contra el uso real y sugiere ajustes. + +Dos cosas a tener en cuenta: + +- Generar un informe tiene un costo variable de IA según la complejidad del análisis, que consume del presupuesto mensual de IA de tu empresa (configurable en Settings). +- La sección Reports está disponible para usuarios admin y editor con la feature habilitada — si no la ves en Settings, pedínosla a través de **Support**. + +--- + +## De dónde vienen tus costos + +El Cost Explorer te dice *cuánto* y *dónde*; estas páginas explican *por qué* un recurso cuesta lo que cuesta: + +- **Estrategia de nodepool** (Spot vs. On-Demand vs. Reserved, ARM vs. AMD) — mirá [Node Pools](/docs/cluster/nodepools) y el tutorial de [Estrategias de Nodepools](/tutorial/nodepool-strategies). +- **Sizing del workload** (CPU/Memory requests, límites de autoscaling) — los requests de un workload son el piso de lo que reserva, y son los que más impactan el costo `idle` en Kubecost cuando quedan configurados por encima del uso real. Mirá la configuración de [Web Service](/docs/project/workload/webservice). +- **Uptime del cluster** — si un cluster no necesita correr 24/7, un [apagado programado](/docs/cluster/shutdown-cluster) deja de generar costo durante esa ventana horaria. + +--- + +## Si no ves un desglose de costos + +El desglose por recurso del Cost Explorer depende de que las **Cost Allocation Tags** estén activas en la cuenta de AWS. SleakOps las activa automáticamente durante el onboarding, pero AWS puede tardar unos días en propagarlas, y en algunas cuentas la activación necesita un empujón manual. + +Si todavía no están activas, el Cost Explorer para esa cuenta solo va a mostrar el costo total diario de la cuenta, sin desglose por recurso. Si te pasa esto: + +1. Buscá una notificación titulada **"CostAllocationTags are not active in your AWS root account"** — lleva directo a la consola de AWS Cost Management. +2. Seguí ese link y activá los tags que aparecen ahí (`Model`, `Name`, `Cluster`, `ClusterId`, `Environment`, `Dependency`). +3. El desglose queda disponible una vez que AWS termina de propagar los tags — no es instantáneo, esperá un rato. + +--- + +## Siguiente paso: reducir lo que gastás + +Una vez que sabés a dónde va tu gasto, [Estrategias de optimización de costos en AWS](/tutorial/optimize-aws-costs) y el tutorial de [Estrategias de Nodepools](/tutorial/nodepool-strategies) recorren formas concretas de bajarlo — instancias Spot, right-sizing, Graviton, políticas de ciclo de vida de storage, y más. diff --git a/content/tutorials/es/deploy-datadog-operator.mdx b/content/tutorials/es/deploy-datadog-operator.mdx index dae2552773..704bdb155c 100644 --- a/content/tutorials/es/deploy-datadog-operator.mdx +++ b/content/tutorials/es/deploy-datadog-operator.mdx @@ -1,7 +1,7 @@ --- title: Desplegar Datadog Operator y DatadogAgent en SleakOps sidebar_label: Desplegar Datadog Operator -sidebar_position: 33 +sidebar_position: 34 description: Instalá el Datadog Operator (v2.8.0) y desplegá un DatadogAgent (v7.63.3) en un cluster EKS de SleakOps con toleraciones de NodePool Karpenter, APM, recolección de logs y admission controller. tags: - kubernetes @@ -17,6 +17,10 @@ import { FiExternalLink } from "react-icons/fi"; Instalá el [Datadog Operator ](https://docs.datadoghq.com/containers/datadog_operator/) y desplegá un custom resource `DatadogAgent` en un cluster EKS de SleakOps para habilitar APM, recolección de logs y monitoreo de eventos de Kubernetes. +:::info +Esta es la configuración **avanzada** de Datadog: el Operator gestiona el ciclo de vida del agente mediante CRDs, habilita auto-instrumentación a través del admission controller e incluye toleraciones de NodePool Karpenter. Para una configuración más simple sin esas características, usá la [guía basada en Helm](./install-datadog). +::: + :::info Esta guía fue probada con **DatadogOperator v2.8.0** y **DatadogAgent v7.63.3**. ::: diff --git a/content/tutorials/es/environment-exhaustive-testing-guide.mdx b/content/tutorials/es/environment-exhaustive-testing-guide.mdx index a6aec00583..32250de6c3 100644 --- a/content/tutorials/es/environment-exhaustive-testing-guide.mdx +++ b/content/tutorials/es/environment-exhaustive-testing-guide.mdx @@ -1,7 +1,457 @@ --- -title: ¿Cómo probar exhaustivametne mi aplicación para validar un ambiente? +title: Guía de pruebas exhaustivas para validar un ambiente +sidebar_label: Guía de pruebas exhaustivas sidebar_position: 4 -description: ¿Cómo probar exhaustivametne mi aplicación para validar un ambiente? +description: Un checklist completo de pruebas para validar que tu aplicación funciona correctamente después de migrar a una nueva infraestructura en SleakOps. +tags: + - kubernetes + - aws + - performance + - security + - monitoring + - deployment --- -Muy pronto +import Zoom from "react-medium-image-zoom"; +import "react-medium-image-zoom/dist/styles.css"; +import { FiExternalLink } from "react-icons/fi"; + +Un checklist completo de pruebas para validar que tu aplicación funciona correctamente después de migrar a una nueva infraestructura en SleakOps. + +## Antes de correr cualquier test: costo vs. riesgo + +Cada sección de esta guía tiene un costo: tiempo de preparación, overhead de infraestructura y esfuerzo de desarrollo. Antes de ejecutar una sección, evaluá si el riesgo que cubre es real para tu aplicación y si la inversión es proporcional. + +A veces el mismo riesgo se puede mitigar de forma más económica. En lugar de montar un stack completo de load testing, por ejemplo, cualquier stack de monitoreo que ya tengas te permite accionar de forma proactiva antes de que el rendimiento se degrade y llegue a tus usuarios. La observabilidad se cubre en la [Sección 6 — Observabilidad y alertas](#sección-6-observabilidad-y-alertas). + +Pensá en esta guía como un menú. Elegí las secciones que correspondan a tu tolerancia al riesgo y la criticidad de tu aplicación — no tenés que correrlo todo. + +:::info +No todas las secciones aplican a todas las aplicaciones. Ejecutá las secciones que correspondan a tu setup — si tu aplicación no usa Spot nodes o workers en background, podés saltear esas secciones. Lo importante es cubrir todo lo que sí aplica. +::: + +## Prerrequisitos + +- Tu aplicación está desplegada en un Ambiente de SleakOps con al menos un Proyecto +- Tu Ambiente terminó de desplegarse (todos los workloads en estado `CREATED`) +- Tenés acceso a la Console de SleakOps + +## Paso 0: Descargá el checklist de tu Ambiente + +Antes de ejecutar cualquier prueba, descargá el checklist de tu Ambiente desde la Console de SleakOps. Lista todos los componentes configurados — Web Services, Workers, Cron Jobs, Hooks, Dependencias y Var Groups — para que puedas usarlo como inventario mientras recorrés las secciones siguientes. + +Navegá a tu Ambiente en la Console y hacé clic en el botón **Descargar checklist**. Abrí el archivo Markdown descargado y mantenelo abierto junto a esta guía. + +{/* TODO: screenshot - Página del Ambiente con el botón "Descargar checklist" resaltado */} + +## Sección 1: Pruebas funcionales + +**Aplica a:** todas las aplicaciones. + +Estas son las verificaciones de base. Si algo falla acá, corregilo antes de continuar. + +### Web Services + +Para cada Web Service del checklist: + +1. Abrí la URL del servicio y verificá que responde correctamente (sin páginas de error ni pantalla en blanco) +2. Iniciá y cerrá sesión — verificá que la autenticación y el manejo de sesiones funcionan como se espera +3. Recorré los flujos principales de tu aplicación (los que tus usuarios utilizan con más frecuencia) +4. Verificá que la aplicación está leyendo la configuración del nuevo ambiente — que no apunta a bases de datos o servicios externos de un deploy anterior + +### Workers + +Para cada Worker del checklist: + +1. Dispará una acción en tu aplicación que encole un job en background (por ejemplo: enviar un email, procesar una subida de archivo, ejecutar un reporte) +2. Confirmá que el job se completa exitosamente — revisá el panel de estado de jobs de tu aplicación, los logs, o el resultado esperado + +### Cron Jobs + +Para cada Cron Job del checklist: + +1. En [Headlamp ](https://headlamp.dev/) (disponible como addon en tu Cluster de SleakOps), navegá a **Workloads → CronJobs** en el namespace de tu Ambiente +2. Verificá que el timestamp de **Last Schedule** es reciente y que el de **Last Successful** coincide +3. Si la próxima ejecución programada está lejos, podés disparar un job manual desde Headlamp para verificar que se ejecuta sin errores + +### Hooks + +Para cada Hook del checklist: + +1. Dispará un deploy desde la Console de SleakOps +2. Una vez completado el deploy, revisá los logs del deployment en la Console para confirmar que cada Hook se ejecutó y terminó exitosamente (código de salida 0) + +### Dependencias + +Para cada Dependencia del checklist (PostgreSQL, Redis, S3, RabbitMQ, etc.): + +1. Usá una funcionalidad de tu aplicación que utilice esa dependencia — por ejemplo, creá un registro (PostgreSQL), cacheá algo (Redis), subí un archivo (S3) +2. Confirmá que la operación se completa sin errores + +--- + +## Sección 2: Pruebas de performance y stress + +**Aplica a:** todas las aplicaciones expuestas a tráfico real de usuarios. + +El objetivo es establecer un baseline de performance y confirmar que la nueva infraestructura soporta la carga esperada. + +:::tip +Si tenés métricas de performance de tu infraestructura anterior (tiempos de respuesta, throughput), comparalos con los resultados de estas pruebas. +::: + +### Herramientas recomendadas + +| Herramienta | Licencia | Para qué sirve | +| --- | --- | --- | +| [k6 ](https://k6.io/docs/) | AGPL-3.0 | Tests de carga con scripts en JavaScript — load, stress, spike, endurance | +| [Locust ](https://docs.locust.io/) | MIT | Tests de carga en Python con UI web incluida | +| [Artillery ](https://www.artillery.io/docs/) | MPL-2.0 | Escenarios de stress y spike configurados en YAML | + +Monitoreá CPU, memoria, requests/seg y latencia en tiempo real con **Grafana**, disponible como addon en tu Cluster de SleakOps. + +### Load test — verificar el tráfico normal + +Ejecutá un test que simule tu volumen de tráfico normal durante al menos 10 minutos. + +- **Pasa:** El tiempo de respuesta p95 está dentro del umbral aceptable; la tasa de errores está por debajo del 1% +- **Falla:** La latencia se dispara, la tasa de errores sube, o los pods se reinician bajo carga normal + +### Stress test — encontrar el punto de quiebre + +Aumentá la carga gradualmente más allá del tráfico normal hasta que el sistema se degrade. Esto te dice cuánto margen tenés. + +- **Pasa:** El sistema degrada de forma controlada (respuestas más lentas, no crashes ni errores 500) +- **Falla:** Los pods crashean, las colas se desbordan, o la aplicación devuelve errores no controlados + +### Spike test — verificar el auto-escalado + +:::tip +Esta prueba solo produce resultados significativos si el **Autoscaling (HPA)** está habilitado en tus Web Services. Consultá la [documentación de Web Service](/docs/project/workload/webservice) para aprender cómo configurarlo. +::: + +Enviá una ráfaga repentina de tráfico (5–10× lo normal) durante 2–3 minutos y luego volvé a la normalidad. + +- **Pasa:** Karpenter y HPA crean nuevos pods; el pico es absorbido; el sistema vuelve a escalar hacia abajo después del burst +- **Falla:** Los pods se saturan antes de que aparezcan nuevos; se pierden requests + +### Endurance test — detectar memory leaks + +Ejecutá una carga moderada sostenida durante 2–4 horas. Monitoreá el uso de memoria durante toda la prueba en **Grafana** ([instalalo como addon en tu Cluster](/docs/cluster/addons/grafana)) — una tendencia sostenida hacia arriba a lo largo del tiempo es la principal señal de un memory leak. + +- **Pasa:** El uso de memoria es estable; no hay reinicios de pods; los tiempos de respuesta se mantienen constantes +- **Falla:** La memoria crece progresivamente; los pods terminan siendo eliminados por OOM; la latencia se degrada con el tiempo + +--- + +## Sección 3: Pruebas de seguridad + +**Aplica a:** todas las aplicaciones con endpoints públicos. + +### TLS y HTTPS + +1. Analizá tu dominio principal con [SSL Labs ](https://www.ssllabs.com/ssltest/) +2. **Pasa:** Grado A o A+, certificado que no expira en los próximos 30 días, cadena de certificados completa y válida +3. **Falla:** Grado B o inferior, certificado expirado o próximo a expirar, cadena rota + +### Headers de seguridad HTTP + +1. Analizá tu dominio principal con [securityheaders.com ](https://securityheaders.com/) +2. **Pasa:** Grado A — HSTS, X-Content-Type-Options, X-Frame-Options y Content-Security-Policy presentes +3. **Falla:** Grado C o inferior, o HSTS ausente + +### Política CORS + +Ejecutá el siguiente comando reemplazando `TU_DOMINIO` con la URL de tu aplicación: + +```bash +curl -I -H "Origin: https://sitio-malicioso.example.com" https://TU_DOMINIO/api/ +``` + +- **Pasa:** La respuesta no incluye `Access-Control-Allow-Origin: https://sitio-malicioso.example.com` +- **Falla:** La respuesta refleja el origen — la política CORS es demasiado permisiva + +### Rate limiting + +Si tu aplicación tiene rate limiting configurado, verificá que funciona: + +```bash +for i in {1..100}; do curl -s -o /dev/null -w "%{http_code}\n" https://TU_DOMINIO/login; done +``` + +- **Pasa:** Después de N requests, las respuestas empiezan a devolver `429 Too Many Requests` +- **Falla:** Los 100 requests devuelven `200` — el rate limiting no está activo + +### Rutas sensibles + +Verificá que las rutas comunes sensibles no son públicamente accesibles: + +```bash +curl -I https://TU_DOMINIO/.env +curl -I https://TU_DOMINIO/admin/ +curl -I https://TU_DOMINIO/.git/config +``` + +- **Pasa:** Todos devuelven `404` o `403` +- **Falla:** Alguno devuelve `200` — esos archivos están expuestos públicamente + +### Autenticación en endpoints protegidos + +Elegí un endpoint de API que requiera autenticación y probalo sin credenciales: + +```bash +curl -I https://TU_DOMINIO/api/recurso-protegido/ +``` + +- **Pasa:** Devuelve `401 Unauthorized` o `403 Forbidden` +- **Falla:** Devuelve `200` — el endpoint no tiene autenticación + +### Auditoría de dependencias + +Ejecutá un análisis de vulnerabilidades en las dependencias de tu aplicación: + +```bash +# Node.js +npm audit --audit-level=high + +# Python +pip-audit +``` + +- **Pasa:** Sin vulnerabilidades altas o críticas +- **Falla:** Se encontraron CVEs altos o críticos — revisá y actualizá los paquetes afectados antes de ir a producción + +:::info +Para un análisis automatizado más profundo, herramientas como [OWASP ZAP ](https://www.zaproxy.org/docs/) (DAST) y [Trivy ](https://trivy.dev/latest/docs/) (escaneo de contenedores y dependencias) pueden dar mayor cobertura. +::: + +--- + +## Sección 4: Resiliencia de infraestructura + +### 4a — Aplicación sin cache + +**Aplica a:** aplicaciones que usan Redis para caching, sesiones o rate limiting. + +El objetivo es confirmar que tu aplicación degrada de forma controlada cuando Redis no está disponible, en lugar de caerse completamente. + +1. En la Console de SleakOps, andá a **Var Groups** y cambiá temporalmente la URL de conexión de Redis a un host inalcanzable (por ejemplo, `redis://invalid-host:6379`) +2. Dispará un deploy — la aplicación levantará apuntando a un Redis inexistente +3. Recorré los flujos principales de tu aplicación +4. Tomá nota de qué funcionalidades fallan o se degradan — esto es comportamiento esperado, no un pass/fail en sí mismo +5. **Pasa:** La aplicación devuelve mensajes de error controlados o hace fallback de forma elegante; no lanza errores 500 no controlados ni crashea +6. **Falla:** Toda la aplicación queda inaccesible, o se exponen excepciones no manejadas a los usuarios +7. Revertí el Var Group a la URL de Redis original, disparé otro deploy, y verificá que la aplicación vuelve a funcionar normalmente + +:::info +Monitoreá también la carga de la base de datos en Grafana durante esta prueba. Si Redis cachea queries, sacarlo puede disparar las conexiones a la DB — verificá que la base de datos pueda absorber la carga adicional. +::: + +### 4b — Interrupción de nodos Spot + +**Aplica a:** ambientes donde algún workload corre en un Spot Node Pool. + +AWS puede recuperar instancias Spot en cualquier momento con un aviso de 2 minutos. Esta prueba verifica que Karpenter reprogramó tus workloads correctamente y que no se pierden requests durante la transición. + +1. Abrí la [consola de AWS Fault Injection Service (FIS) ](https://console.aws.amazon.com/fis/home) +2. Creá un nuevo template de experimento con la acción **`aws:ec2:send-spot-instance-interruptions`** +3. Configurá como target las instancias Spot del node group Spot de tu cluster EKS +4. Iniciá el experimento — AWS envía el aviso de interrupción de 2 minutos a la instancia seleccionada +5. En [Headlamp ](https://headlamp.dev/) (disponible como addon en tu Cluster), observá cómo los pods afectados se reprograman en nodos on-demand +6. Monitoreá la tasa de errores en Grafana durante la interrupción — debe mantenerse dentro del umbral de tu SLA +7. **Pasa:** Los pods se reprograman en menos de 5 minutos; la tasa de errores se mantiene dentro del umbral; no se requiere intervención manual +8. **Falla:** Los pods quedan en estado `Pending`, la tasa de errores se dispara y no se recupera, o la aplicación requiere reinicio manual + +Referencia: [AWS FIS — Interrupciones de Spot Instances ](https://docs.aws.amazon.com/fis/latest/userguide/actions-reference.html) + +### 4c — Resiliencia de workers + +**Aplica a:** aplicaciones con Workers en background. + +#### Escenario 1: Poison pill (tarea malformada) + +Una poison pill es una tarea que no puede procesarse — datos malformados, un campo requerido faltante, o una referencia inválida. Es uno de los modos de falla más comunes en producción. + +:::info +Este escenario es específico de tu aplicación. El comportamiento exacto (reintentos, enrutamiento al DLQ, logging de errores) depende de cómo tu aplicación maneja los errores en su stack de procesamiento de tareas (Celery, Sidekiq, BullMQ, etc.). Revisá la documentación de tu framework antes de ejecutar esta prueba. +::: + +1. Identificá un tipo de tarea que procesen los workers de tu aplicación +2. Enviá esa tarea con datos intencionalmente inválidos o malformados (campo requerido faltante, ID inválido, payload corrupto) +3. **Pasa:** El worker registra el error, mueve la tarea a la Dead Letter Queue (DLQ) después de los reintentos configurados, y continúa procesando otras tareas normalmente +4. **Falla:** El worker crashea, deja de procesar todas las tareas, o descarta el error silenciosamente sin enrutarlo al DLQ + +#### Escenario 2: Saturación de cola + +Verifica que no se pierden tareas bajo alta carga y que el auto-escalado funciona como se espera. + +1. Enviá una ráfaga de tareas — apuntá a 5–10× el volumen típico +2. Monitoreá la profundidad de la cola en Grafana o el panel de administración de tu message broker (RabbitMQ, SQS, etc.) +3. Si KEDA está configurado para tus workers ([consultá la documentación del addon KEDA](/docs/cluster/addons/keda)), observá cómo escala pods adicionales automáticamente a medida que crece la cola +4. Esperá a que todas las tareas se completen y verificá que el total procesado coincide con el total enviado +5. **Pasa:** Todas las tareas se procesan eventualmente; ninguna se pierde; la profundidad de la cola vuelve a cero +6. **Falla:** Se pierden tareas, la cola crece indefinidamente, o los pods de workers crashean bajo carga + +### 4d — Dependencias externas + +#### PostgreSQL (RDS) + +Si tu instancia de RDS está configurada como Multi-AZ: + +1. Desde la consola de AWS RDS, iniciá un **Reboot with failover** en tu instancia de DB +2. Monitoreá tu aplicación — debe reconectarse automáticamente en 30–60 segundos +3. **Pasa:** La aplicación se reconecta sin reinicio; sin pérdida de datos; los usuarios pueden ver un breve error durante la ventana de failover +4. **Falla:** La aplicación requiere reinicio manual para reconectarse, o ocurre corrupción de datos + +#### Amazon S3 + +1. Desde tu aplicación, subí un archivo de prueba a S3 +2. Leé el archivo de vuelta y verificá su contenido +3. Eliminá el archivo de prueba +4. **Pasa:** Las tres operaciones se completan exitosamente con los permisos configurados en SleakOps +5. **Falla:** Alguna operación falla — revisá la configuración de IAM Role for Service Account (IRSA) en SleakOps + +#### Redis + +1. En la Console de SleakOps, andá a **Var Groups** y cambiá temporalmente la URL de conexión de Redis a un host inalcanzable +2. Dispará un deploy — la aplicación no podrá conectarse a Redis +3. Revertí el Var Group a la URL original y desplegá nuevamente +4. **Pasa:** La aplicación se reconecta a Redis automáticamente sin necesitar un reinicio manual +5. **Falla:** La aplicación requiere reinicio para reconectarse a Redis + +#### APIs de terceros + +Para cada API externa con la que tu aplicación se integra: + +1. Bloqueá temporalmente el dominio de la API a nivel de red, o usá un mock que devuelva errores +2. Dispará el flujo de la aplicación que llama a esa API +3. **Pasa:** La aplicación maneja el fallo de forma elegante — muestra un mensaje de error amigable al usuario, usa un fallback, o encola el request para reintento +4. **Falla:** El error de la API externa se propaga como un 500 no controlado al usuario + +--- + +## Sección 5: Escalabilidad horizontal + +**Aplica a:** aplicaciones donde se espera que corran múltiples réplicas simultáneamente. + +### Comportamiento con múltiples réplicas + +1. Escalá tu Web Service principal a 3 réplicas desde la Console de SleakOps +2. Enviá una serie de requests y verificá que todas las réplicas los manejan correctamente (revisá los logs en Headlamp — deberías ver requests distribuidos entre distintos nombres de pods) +3. **Pasa:** Todas las réplicas sirven requests correctamente; sin errores relacionados al estado compartido +4. **Falla:** Aparecen errores cuando un request llega a una réplica diferente a la que inició la sesión (problema de sticky sessions) — la causa de fondo es estado de sesión guardado en la memoria del Pod y no en un backend compartido; las [sticky sessions](/tutorial/sticky-sessions) pueden mitigarlo mientras externalizás ese estado + +### Estado compartido entre réplicas + +Si tu aplicación almacena estado en memoria (sesiones de usuario, archivos subidos, locks), verificá que ese estado se guarda en un backend compartido — no en la memoria local del pod. + +1. Iniciá una sesión en tu aplicación (por ejemplo, iniciá sesión) +2. Escalá hacia abajo el pod que manejó tu request (usá Headlamp para identificar cuál fue) +3. Hacé otro request — un pod diferente debería manejarlo +4. **Pasa:** La sesión se mantiene; el nuevo pod puede leer el estado desde Redis/DB +5. **Falla:** La sesión se pierde; te cerraron la sesión o recibís un error + +### Auto-escalado bajo carga + +Si HPA o KEDA está configurado para tus workloads: + +1. Ejecutá un load test (ver Sección 2) y observá el conteo de pods en Headlamp +2. **Pasa:** Se crean nuevos pods a medida que aumenta la carga y se eliminan cuando disminuye; la aplicación maneja la transición sin errores +3. **Falla:** Los pods no se crean a tiempo y la aplicación se satura, o los nuevos pods fallan sus readiness probes + +--- + +## Sección 6: Observabilidad y alertas + +**Aplica a:** todas las aplicaciones en producción. + +La observabilidad no es opcional — si algo falla después de la migración, necesitás poder detectarlo y diagnosticarlo rápidamente. + +### Logs + +1. Realizá una acción en tu aplicación que genere una entrada de log (por ejemplo, iniciá sesión, disparé un error) +2. Abrí **Loki** (disponible como addon en tu Cluster) y buscá los logs de tu aplicación +3. **Pasa:** La entrada de log aparece en Loki en pocos segundos +4. **Falla:** No aparecen logs — verificá que tu aplicación escriba a stdout/stderr, no a un archivo dentro del contenedor + +### Métricas en Grafana + +1. Abrí **Grafana** (disponible como addon en tu Cluster) +2. Verificá que existan dashboards para tu aplicación mostrando como mínimo: uso de CPU y uso de memoria +3. **Pasa:** Todas las métricas están pobladas con datos recientes +4. **Falla:** Faltan métricas o muestran "No data" — verificá que Prometheus esté scrapeando el endpoint de métricas de tu aplicación + +### Visibilidad de errores + +1. Dispará intencionalmente un error 500 en tu aplicación (por ejemplo, llamá a un endpoint con parámetros inválidos que cause una excepción no manejada) +2. Verificá que el error aparece en tu herramienta de tracking de errores (Grafana, Loki, Sentry, CloudWatch, etc.) +3. **Pasa:** El error es visible en 1–2 minutos con suficiente contexto para diagnosticar (stack trace, parámetros del request) +4. **Falla:** El error es silencioso — no hay visibilidad sobre qué salió mal + +--- + +## Sección 7: Deploy y rollback + +**Aplica a:** todas las aplicaciones. + +El ciclo de deploy y rollback es una de las cosas más críticas para validar antes de confiar en un nuevo ambiente. + +### Deploy sin downtime + +:::warning +Para que los deploys sin downtime funcionen correctamente, tus Web Services deben tener las **readiness probes** y el **`terminationGracePeriod`** bien configurados. Kubernetes usa la readiness probe para saber cuándo un nuevo pod está listo para recibir tráfico, y el termination grace period para permitir que los requests en vuelo se completen antes de detener el pod viejo. Consultá la [documentación de Web Service](/docs/project/workload/webservice) para aprender cómo configurarlos. +::: + +1. Mientras enviás tráfico continuo a tu aplicación (podés usar un `watch curl` simple o un load test liviano), disparé un nuevo deploy desde la Console de SleakOps +2. Monitoreá la tasa de errores durante el deploy +3. **Pasa:** La tasa de errores se mantiene en 0% (o dentro de límites aceptables) durante todo el deploy; no se pierden requests +4. **Falla:** La tasa de errores se dispara durante el deploy — verificá que las readiness probes y el termination grace period estén correctamente configurados en tus workloads + +### Actualización de Var Group + +1. Hacé un cambio pequeño en uno de tus Var Groups (por ejemplo, cambiá una variable de entorno no crítica) +2. Dispará un deploy +3. Después del deploy, verificá en tu aplicación o en los logs que el nuevo valor está activo +4. **Pasa:** El nuevo valor se aplica sin problemas +5. **Falla:** La aplicación sigue usando el valor anterior, o el deploy falla por el cambio + +### Prueba de rollback + +Esta es la prueba más importante de esta sección. Verificá que podés recuperarte de un deploy fallido antes de necesitarlo. + +1. Anotá la versión actual de tu aplicación +2. Desplegá una nueva versión (puede ser un cambio trivial — un mensaje de log, un comentario) +3. Desde la Console de SleakOps, hacé rollback a la versión anterior +4. Verificá que la aplicación está corriendo la versión anterior y que funciona correctamente (ejecutá las pruebas funcionales de la Sección 1) +5. **Pasa:** El rollback se completa en minutos; la versión anterior funciona correctamente +6. **Falla:** El rollback falla, tarda demasiado, o la versión anterior no funciona después del rollback + +### Migraciones de base de datos (si aplica) + +Si tu aplicación ejecuta migraciones de base de datos como parte del deploy: + +1. Verificá que la última migración se ejecutó exitosamente revisando los logs del deployment en la Console +2. Verificá que la migración es backward-compatible — si necesitaras hacer rollback de la aplicación, la versión anterior debería seguir funcionando con el schema actual de la base de datos +3. **Pasa:** La migración se ejecutó exitosamente y es backward-compatible +4. **Falla:** La migración falló, o hacer rollback de la app rompería con el nuevo schema + +--- + +## Referencia de herramientas + +| Categoría | Herramienta | Licencia | Docs | +| --- | --- | --- | --- | +| Load testing | [k6 ](https://k6.io/docs/) | AGPL-3.0 | https://k6.io/docs/ | +| Load testing | [Locust ](https://docs.locust.io/) | MIT | https://docs.locust.io/ | +| Load testing | [Artillery ](https://www.artillery.io/docs/) | MPL-2.0 | https://www.artillery.io/docs/ | +| Auditoría TLS | [SSL Labs ](https://www.ssllabs.com/ssltest/) | Gratuito (online) | https://www.ssllabs.com/ssltest/ | +| Headers de seguridad | [securityheaders.com ](https://securityheaders.com/) | Gratuito (online) | https://securityheaders.com/ | +| Scanner DAST | [OWASP ZAP ](https://www.zaproxy.org/docs/) | Apache-2.0 | https://www.zaproxy.org/docs/ | +| Scan contenedores/deps | [Trivy ](https://trivy.dev/latest/docs/) | Apache-2.0 | https://trivy.dev/latest/docs/ | +| Auditoría deps | `npm audit` | Built-in | https://docs.npmjs.com/cli/v10/commands/npm-audit | +| Auditoría deps | [pip-audit ](https://pypi.org/project/pip-audit/) | Apache-2.0 | https://pypi.org/project/pip-audit/ | +| Chaos (Spot) | [AWS FIS ](https://docs.aws.amazon.com/fis/latest/userguide/) | Managed (free tier) | https://docs.aws.amazon.com/fis/latest/userguide/ | +| UI del Cluster | [Headlamp ](https://headlamp.dev/) | Apache-2.0 | Addon de SleakOps | +| Métricas | Grafana | AGPL-3.0 | Addon de SleakOps | +| Logs | Loki | AGPL-3.0 | Addon de SleakOps | +| Métricas | Prometheus | Apache-2.0 | Addon de SleakOps | diff --git a/content/tutorials/es/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas.mdx b/content/tutorials/es/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas.mdx index f6531ea315..2692e55b00 100644 --- a/content/tutorials/es/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas.mdx +++ b/content/tutorials/es/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas.mdx @@ -22,9 +22,9 @@ Conectá tu VPC de AWS a MongoDB Atlas mediante VPC Peering para acceso privado ## Prerrequisitos -- Una cuenta de MongoDB Atlas con un cluster de tier \*\*M10 o superior\*\* +- Una cuenta de MongoDB Atlas con un cluster de tier **M10 o superior** - Una cuenta de AWS con una VPC donde corren tus workloads -- Rol de \*\*Project Owner\*\* en MongoDB Atlas +- Rol de **Project Owner** en MongoDB Atlas - DNS hostnames y DNS resolution habilitados en tu VPC de AWS @@ -37,18 +37,18 @@ Conectá tu VPC de AWS a MongoDB Atlas mediante VPC Peering para acceso privado El VPC Peering es la opción correcta cuando: -- Tus workloads corren dentro de una VPC de AWS en la \*\*misma región\*\* que tu cluster de Atlas -- Necesitás \*\*conectividad privada\*\* — el tráfico nunca sale del backbone de AWS -- Usás clusters de Atlas en tier \*\*M10 o superior\*\* +- Tus workloads corren dentro de una VPC de AWS en la **misma región** que tu cluster de Atlas +- Necesitás **conectividad privada** — el tráfico nunca sale del backbone de AWS +- Usás clusters de Atlas en tier **M10 o superior** - Tus recursos corren en EKS, EC2, u otro servicio dentro de la VPC -El VPC Peering \*\*no está disponible\*\* en estos casos: +El VPC Peering **no está disponible** en estos casos: -- Tiers de cluster \*\*M0, M2, M5 o Serverless\*\* — no soportan peering -- \*\*Peering multi-cloud\*\* — Atlas no soporta peering entre distintos proveedores (ej: GCP y AWS) -- \*\*CIDRs solapados\*\* — si el CIDR de tu VPC de AWS se solapa con el de Atlas, el peering no puede establecerse +- Tiers de cluster **M0, M2, M5 o Serverless** — no soportan peering +- **Peering multi-cloud** — Atlas no soporta peering entre distintos proveedores (ej: GCP y AWS) +- **CIDRs solapados** — si el CIDR de tu VPC de AWS se solapa con el de Atlas, el peering no puede establecerse :::warning @@ -59,12 +59,12 @@ Si alguno de los casos anteriores aplica, pasá directamente a [Alternativa: Whi ### Alternativa: Whitelist de la IP del NAT Gateway -Si el peering no es una opción, podés permitir conexiones a Atlas desde tu VPC registrando la IP pública de tu \*\*NAT Gateway\*\*: +Si el peering no es una opción, podés permitir conexiones a Atlas desde tu VPC registrando la IP pública de tu **NAT Gateway**: -1. En la consola de AWS, navegá a \*\*VPC → NAT Gateways\*\* y copiá la \*\*Elastic IP\*\* asociada a tu NAT Gateway. -2. En MongoDB Atlas, navegá a \*\*Network Access → IP Access List → Add IP Address\*\*. -3. Ingresá la Elastic IP con una descripción como \`NAT Gateway - produccion\`. +1. En la consola de AWS, navegá a **VPC → NAT Gateways** y copiá la **Elastic IP** asociada a tu NAT Gateway. +2. En MongoDB Atlas, navegá a **Network Access → IP Access List → Add IP Address**. +3. Ingresá la Elastic IP con una descripción como `NAT Gateway - produccion`. Tus workloads se conectarán a Atlas a través de internet vía el NAT, sin necesidad de peering. @@ -84,28 +84,26 @@ Esta opción tiene mayor latencia que el peering, pero funciona con cualquier ti Antes de configurar el peering en Atlas, necesitás los siguientes valores de tu cuenta de AWS. -\*\*Obtener el Account ID\*\* +**Obtener el Account ID** -Hacé clic en tu nombre de usuario en la esquina superior derecha de la consola de AWS. Tu \*\*Account ID\*\* de 12 dígitos aparece en el menú desplegable. +Hacé clic en tu nombre de usuario en la esquina superior derecha de la consola de AWS. Tu **Account ID** de 12 dígitos aparece en el menú desplegable. +{/* TODO: screenshot - Consola de AWS mostrando el Account ID en el menú desplegable */} +**Obtener el VPC ID y CIDR** -\*\*Obtener el VPC ID y CIDR\*\* +En la consola de AWS, buscá **VPC** y abrí **Your VPCs**. Seleccioná la VPC donde corren tus workloads y anotá el **VPC ID** (comienza con `vpc-`) y el **IPv4 CIDR** (ej: `10.0.0.0/16`). +{/* TODO: screenshot - Consola de AWS mostrando la lista de VPCs con las columnas VPC ID e IPv4 CIDR */} -En la consola de AWS, buscá \*\*VPC\*\* y abrí \*\*Your VPCs\*\*. Seleccioná la VPC donde corren tus workloads y anotá el \*\*VPC ID\*\* (comienza con \`vpc-\`) y el \*\*IPv4 CIDR\*\* (ej: \`10.0.0.0/16\`). - - - - -| \*\*Campo\*\* | \*\*Dónde encontrarlo\*\* | +| **Campo** | **Dónde encontrarlo** | | --------------------------- | ------------------------------------------------------ | -| \*\*Account ID\*\* | Menú desplegable en la esquina superior derecha de AWS | -| \*\*VPC ID\*\* | VPC → Your VPCs (comienza con \`vpc-\`) | -| \*\*VPC CIDR\*\* | VPC → Your VPCs → columna IPv4 CIDR | -| \*\*Application VPC Region\*\* | La región de AWS donde vive tu VPC | +| **Account ID** | Menú desplegable en la esquina superior derecha de AWS | +| **VPC ID** | VPC → Your VPCs (comienza con `vpc-`) | +| **VPC CIDR** | VPC → Your VPCs → columna IPv4 CIDR | +| **Application VPC Region** | La región de AWS donde vive tu VPC | --- @@ -114,29 +112,41 @@ En la consola de AWS, buscá \*\*VPC\*\* y abrí \*\*Your VPCs\*\*. Seleccioná ### Paso 2 — Crear la conexión de Peering en Atlas -1. En MongoDB Atlas, navegá a \*\*Network Access\*\* en el menú lateral izquierdo. -2. Hacé clic en la pestaña \*\*Peering\*\* y luego en \*\*Add Peering Connection\*\*. - - - +1. En MongoDB Atlas, navegá a **Network Access** en el menú lateral izquierdo. +2. Hacé clic en la pestaña **Peering** y luego en **Add Peering Connection**. -3. Seleccioná \*\*AWS\*\* como proveedor cloud y completá el formulario con los valores del Paso 1: - - \*\*Account ID\*\* — tu número de cuenta de AWS de 12 dígitos - - \*\*VPC ID\*\* — el ID de VPC que comienza con \`vpc-\` - - \*\*VPC CIDR\*\* — el rango de IPs de tu VPC - - \*\*Application VPC Region\*\* — la región de AWS - - \*\*Atlas VPC CIDR\*\* — Atlas sugerirá un rango (ej: \`192.168.240.0/21\`); conservalo salvo que entre en conflicto con tu red + + Pestaña Peering en Network Access de MongoDB Atlas + +3. Seleccioná **AWS** como proveedor cloud y completá el formulario con los valores del Paso 1: + - **Account ID** — tu número de cuenta de AWS de 12 dígitos + - **VPC ID** — el ID de VPC que comienza con `vpc-` + - **VPC CIDR** — el rango de IPs de tu VPC + - **Application VPC Region** — la región de AWS + - **Atlas VPC CIDR** — Atlas sugerirá un rango (ej: `192.168.240.0/21`); conservalo salvo que entre en conflicto con tu red + + Formulario de peering en MongoDB Atlas con los datos de AWS + - -4. Hacé clic en \*\*Initiate Peering\*\*. - - -Atlas mostrará la conexión con estado \*\*"Waiting for Approval"\*\*. La solicitud debe aceptarse ahora desde la consola de AWS. +4. Hacé clic en **Initiate Peering**. +Atlas mostrará la conexión con estado **"Waiting for Approval"**. La solicitud debe aceptarse ahora desde la consola de AWS. + + Conexión de peering en MongoDB Atlas esperando aprobación + --- @@ -144,22 +154,55 @@ Atlas mostrará la conexión con estado \*\*"Waiting for Approval"\*\*. La solic ### Paso 3 — Aceptar la solicitud de Peering en AWS -1. En la consola de AWS, navegá a \*\*VPC → Peering connections\*\*. -2. Verás una conexión con estado \*\*"Pending acceptance"\*\*. +1. En la consola de AWS, navegá a **VPC → Peering connections**. +2. Verás una conexión con estado **"Pending acceptance"**. + + Lista de conexiones de VPC Peering en AWS con solicitud pendiente + + + Detalle de la solicitud de VPC Peering pendiente en AWS + - -3. Seleccioná la conexión, hacé clic en \*\*Actions → Accept request\*\*. +3. Seleccioná la conexión, hacé clic en **Actions → Accept request**. 4. Revisá los detalles en el modal (VPCs, CIDRs, regiones) y confirmá. - - - -Una vez aceptada, el estado cambia a \*\*"Active"\*\* en AWS y \*\*"Available"\*\* en Atlas. - - - + + Diálogo para aceptar la solicitud de VPC peering en AWS + + + + Confirmación de solicitud de VPC peering aceptada en AWS + + +Una vez aceptada, el estado cambia a **"Active"** en AWS y **"Available"** en Atlas. + + + Estado de conexión de peering Available en MongoDB Atlas + + + + Confirmación del estado Available de la conexión de peering en MongoDB Atlas + --- @@ -170,15 +213,26 @@ Una vez aceptada, el estado cambia a \*\*"Active"\*\* en AWS y \*\*"Available"\* Para que el tráfico fluya a través de la conexión de peering, debés agregar una ruta en la Route Table de las subnets donde corren tus workloads. -1. En la consola de AWS, navegá a \*\*VPC → Route Tables\*\*. +1. En la consola de AWS, navegá a **VPC → Route Tables**. 2. Seleccioná la Route Table asociada a las subnets de tus workloads. -3. Abrí la pestaña \*\*Routes\*\* y hacé clic en \*\*Edit routes → Add route\*\*: - - \*\*Destination\*\*: el CIDR de la VPC de Atlas (ej: \`192.168.240.0/21\`) - - \*\*Target\*\*: seleccioná \*\*Peering Connection\*\* y elegí la conexión que acabás de crear -4. Hacé clic en \*\*Save changes\*\*. - - - +3. Abrí la pestaña **Routes** y hacé clic en **Edit routes → Add route**: + - **Destination**: el CIDR de la VPC de Atlas (ej: `192.168.240.0/21`) + - **Target**: seleccioná **Peering Connection** y elegí la conexión que acabás de crear +4. Hacé clic en **Save changes**. + + + Lista de Route Tables en AWS + + + + Route Table de AWS con la ruta de peering de Atlas agregada + --- @@ -189,25 +243,25 @@ Para que el tráfico fluya a través de la conexión de peering, debés agregar Creá un Security Group que permita tráfico de salida hacia los puertos de MongoDB Atlas: -1. En la consola de AWS, navegá a \*\*EC2 → Security Groups → Create security group\*\*. -2. Agregá una regla de \*\*salida (outbound)\*\*: +1. En la consola de AWS, navegá a **EC2 → Security Groups → Create security group**. +2. Agregá una regla de **salida (outbound)**: -| \*\*Tipo\*\* | \*\*Protocolo\*\* | \*\*Rango de puertos\*\* | \*\*Destino\*\* | +| **Tipo** | **Protocolo** | **Rango de puertos** | **Destino** | | ---------- | ------------- | -------------------- | ------------------------------------------------ | -| Custom TCP | TCP | 27015 – 27017 | CIDR de la VPC de Atlas (ej: \`192.168.240.0/21\`) | +| Custom TCP | TCP | 27015 – 27017 | CIDR de la VPC de Atlas (ej: `192.168.240.0/21`) | 3. Asociá este Security Group a las instancias EC2, node groups de EKS u otros recursos que necesiten conectarse a Atlas. :::tip -Si usás \*\*EKS con Karpenter\*\*, agregá el siguiente tag al Security Group para que Karpenter lo detecte y aplique automáticamente: +Si usás **EKS con Karpenter**, agregá el siguiente tag al Security Group para que Karpenter lo detecte y aplique automáticamente: -| \*\*Key\*\* | \*\*Value\*\* | -| -------------------------- | -------------------------- | -| \`karpenter.sh/discovery\` | \`YOUR_CLUSTER_NAME\` | +| **Key** | **Value** | +| -------------------------- | --------------------- | +| `karpenter.sh/discovery` | `YOUR_CLUSTER_NAME` | ::: @@ -220,10 +274,9 @@ Si usás \*\*EKS con Karpenter\*\*, agregá el siguiente tag al Security Group p Crear la conexión de peering no es suficiente — también debés habilitar el acceso a nivel de red. -En MongoDB Atlas, navegá a \*\*Network Access → IP Access List → Add IP Address\*\* e ingresá el \*\*CIDR de tu VPC de AWS\*\* (ej: \`10.0.0.0/16\`). - - +En MongoDB Atlas, navegá a **Network Access → IP Access List → Add IP Address** e ingresá el **CIDR de tu VPC de AWS** (ej: `10.0.0.0/16`). +{/* TODO: screenshot - MongoDB Atlas IP Access List con el CIDR de la VPC agregado */} --- @@ -234,29 +287,55 @@ En MongoDB Atlas, navegá a \*\*Network Access → IP Access List → Add IP Add Si tu equipo accede a MongoDB Atlas mediante una VPN como Pritunl, la resolución DNS estándar no funcionará sobre el peering por defecto. Seguí estos pasos para habilitarla: -\*\*Habilitar Custom DNS en Atlas\*\* - +**Habilitar Custom DNS en Atlas** -En Atlas, navegá a \*\*Project → Settings\*\* y habilitá \*\*"Using Custom DNS on AWS with VPC peering"\*\*. +En Atlas, navegá a **Project → Settings** y habilitá **"Using Custom DNS on AWS with VPC peering"**. + + Configuración de Project en MongoDB Atlas con Custom DNS para VPC peering habilitado + +**Usar el connection string de Peering privado** -\*\*Usar el connection string de Peering privado\*\* +Al conectarte al cluster, seleccioná **"Private IP for Peering"** en el modal de conexión. Esto provee un hostname que resuelve a la IP privada del cluster. -Al conectarte al cluster, seleccioná \*\*"Private IP for Peering"\*\* en el modal de conexión. Esto provee un hostname que resuelve a la IP privada del cluster. + + Modal de conexión de MongoDB Atlas mostrando la opción Private IP for Peering + + + Connection string privado de peering en MongoDB Atlas + - - -\*\*Agregar la ruta del CIDR de Atlas en Pritunl\*\* +**Agregar la ruta del CIDR de Atlas en Pritunl** En la configuración del servidor de Pritunl, agregá el CIDR de la VPC de Atlas como ruta adicional para que los clientes VPN puedan alcanzarlo. + + Configuración del servidor Pritunl mostrando la ruta del CIDR de Atlas + - + + Servidor Pritunl con la ruta del CIDR de Atlas guardada + Conectate a la VPN y probá la conexión usando la nueva dirección privada. @@ -267,19 +346,19 @@ Conectate a la VPN y probá la conexión usando la nueva dirección privada. ## Verificación -\*\*Desde una instancia EC2 privada:\*\* +**Desde una instancia EC2 privada:** -\`\`\`bash +```bash dnf install -qy mongodb-mongosh-shared-openssl3 mongosh "mongodb+srv://YOUR_CLUSTER_URL" --apiVersion 1 --username YOUR_USERNAME -\`\`\` +``` -\*\*Desde un Pod en EKS:\*\* +**Desde un Pod en EKS:** -\`\`\`yaml +```yaml apiVersion: v1 kind: Pod metadata: @@ -289,13 +368,13 @@ spec: - name: mongodb-client image: mongo:latest command: ["/bin/sh", "-c", "sleep 3600"] -\`\`\` +``` -\`\`\`bash +```bash kubectl exec -it mongodb-client -- \ mongosh "mongodb+srv://YOUR_CLUSTER_URL" --apiVersion 1 --username YOUR_USERNAME -\`\`\` +``` Una conexión exitosa confirma que el peering está funcionando correctamente. diff --git a/content/tutorials/es/install-datadog.mdx b/content/tutorials/es/install-datadog.mdx index f142891008..1896d98482 100644 --- a/content/tutorials/es/install-datadog.mdx +++ b/content/tutorials/es/install-datadog.mdx @@ -1,7 +1,7 @@ --- title: Instalar Datadog en un Cluster EKS de SleakOps sidebar_label: Instalar Datadog -sidebar_position: 34 +sidebar_position: 33 description: Instalá el agente de monitoreo Datadog en un cluster Amazon EKS gestionado por SleakOps usando Helm, con un values.yaml y buenas prácticas recomendadas. tags: - kubernetes @@ -17,6 +17,20 @@ import { FiExternalLink } from "react-icons/fi"; Instalá el agente de monitoreo [Datadog ](https://www.datadoghq.com/) en un cluster EKS de SleakOps usando Helm para obtener visibilidad completa del rendimiento de las aplicaciones y la salud de la infraestructura. +## Helm vs. Datadog Operator — ¿cuál guía usar? + +SleakOps tiene dos tutoriales para instalar Datadog. Cubren enfoques distintos y **no se combinan** — elegí uno según tus necesidades: + +| | **Esta guía (Helm)** | **[Datadog Operator](./deploy-datadog-operator)** | +|---|---|---| +| **Complejidad de setup** | Baja | Alta | +| **Gestión del ciclo de vida** | Manual (upgrades con Helm) | Automática (el Operator gestiona el agente) | +| **Auto-instrumentación** | No | Sí (admission controller) | +| **Toleraciones de NodePool Karpenter** | Manual | Integradas | +| **Ideal para** | Monitoreo rápido, clusters simples | Clusters multi-workload, auto-instrumentación, Karpenter | + +Si no sabés cuál usar, comenzá por acá. + ## Prerrequisitos - Un cluster EKS de SleakOps con `kubectl` configurado @@ -82,6 +96,10 @@ Todos los pods `datadog-agent-*` deberían llegar al estado `Running` en pocos m | **Datadog Operator** | Gestión del ciclo de vida, basado en CRD | Más complejo de configurar | | **Fargate Logging** | Sin gestión de nodos | Solo funciona para cargas específicas | +## Próximos pasos + +¿Necesitás auto-instrumentación, admission controller o toleraciones de NodePool Karpenter? Consultá la guía [Desplegar Datadog Operator](./deploy-datadog-operator) para la configuración avanzada basada en CRDs. + ## Buenas Prácticas - **Protegé la API key:** Guardarla en un Secret de Kubernetes en lugar de directamente en `values.yaml`. diff --git a/content/tutorials/es/lens-cluster-connectivity.mdx b/content/tutorials/es/lens-cluster-connectivity.mdx index ccf4211338..843fb1a2dd 100644 --- a/content/tutorials/es/lens-cluster-connectivity.mdx +++ b/content/tutorials/es/lens-cluster-connectivity.mdx @@ -77,3 +77,7 @@ En el perfil de conexión de Pritunl, activar la opción **Forzar configuración | DEV | `10.110.0.2` | | MGT | `10.120.0.2` | | PRD | `10.130.0.2` | + +## Ver también + +Si los pasos anteriores no resuelven completamente el problema de DNS, puede ser necesario aplicar la configuración DNS de la VPN de forma explícita mediante scripts por sistema operativo. Consultá la guía [Solución Universal de DNS para Pritunl Client](/tutorial/pritunl-dns-universal). diff --git a/content/tutorials/es/migrate-rds-snapshot-between-accounts.mdx b/content/tutorials/es/migrate-rds-snapshot-between-accounts.mdx index 1432701ee0..e082d3546e 100644 --- a/content/tutorials/es/migrate-rds-snapshot-between-accounts.mdx +++ b/content/tutorials/es/migrate-rds-snapshot-between-accounts.mdx @@ -116,7 +116,8 @@ Los snapshots sin cifrado pueden compartirse directamente entre cuentas. Si tu R 1. Ir a **SleakOps → Dependencies → Create**. 2. Seleccionar **Create an RDS from a snapshot**. -3. Ingresar el identificador de la snapshot copiada. +3. Si la snapshot no está cifrada con la clave predeterminada de AWS, ingresar en el campo **KMS Key ID** el ARN completo de la clave KMS usada para la copia (formato: `arn:aws:kms:::key/`). +4. Ingresar el identificador de la snapshot copiada. --- diff --git a/content/tutorials/es/nodepool-strategies.mdx b/content/tutorials/es/nodepool-strategies.mdx index 481495f790..df0302fa74 100644 --- a/content/tutorials/es/nodepool-strategies.mdx +++ b/content/tutorials/es/nodepool-strategies.mdx @@ -20,9 +20,13 @@ Aprendé a configurar nodepools en SleakOps para optimizar costos, mejorar el re ## ¿Qué es un nodepool? -En SleakOps, un **nodepool** es un grupo de nodos EC2 dentro de tu cluster de Kubernetes que comparten la misma configuración — arquitectura, tipo de instancia, modelo de facturación y límites de recursos. Karpenter gestiona el autoscaling dentro de cada pool automáticamente. +En SleakOps, un **nodepool** no es un grupo de máquinas EC2 que ya están corriendo: es la **definición** de un grupo de nodos EC2 que Karpenter puede aprovisionar a demanda. Cada nodepool especifica qué tipo de nodos se pueden crear — arquitectura, tipo de instancia, modelo de facturación y límites de recursos — y Karpenter levanta y elimina nodos que cumplen esa definición automáticamente según la carga, incluso escalando a cero cuando no hay workloads. -Cuando creás un Cluster, SleakOps aprovisiona un conjunto de nodepools por defecto: +:::tip +No confundas el nodepool con las EC2 en sí. El nodepool es la **plantilla**; los nodos EC2 reales aparecen y desaparecen a demanda. +::: + +Cuando creás un Cluster, SleakOps configura un conjunto de nodepools por defecto: | **nodepool** | **Propósito** | |---|---| @@ -37,6 +41,8 @@ Cada Project Environment se asigna a un nodepool. El cambio de asignación es po ## Estrategias de Optimización de Costos +¿Todavía no sabés bien a dónde va tu gasto? Empezá por la [Guía de revisión de costos](/tutorial/cost-review-guide) para leer tus costos actuales antes de aplicar estas estrategias. + ### 1. Spot con Fallback On-Demand La forma más efectiva de reducir costos de cómputo es correr workloads en **instancias Spot** manteniendo **On-Demand como fallback automático**. En SleakOps, configurá esto seleccionando tanto `Spot` como `On-Demand` como Node Types al crear o editar un nodepool. El sistema los prioriza en este orden: **Reserved → Spot → On-Demand**. @@ -59,6 +65,18 @@ Para usar ARM en SleakOps, se deben cumplir tres condiciones: **Ideal para:** servicios escritos en Go, Python o Node.js sin dependencias nativas exclusivas de x86. +### 3. Segmentación de costos por proyecto + +Un nodepool dedicado por proyecto es una estrategia organizacional en la que cada Project Environment corre en su propio pool de cómputo aislado. Los límites de recursos, tipos de instancia y modelos de facturación se configuran de forma independiente para cada proyecto. + +**Ventaja:** control granular. Cada proyecto tiene su propio límite de cómputo — no hay contención de recursos entre proyectos, y podés ajustar la configuración con precisión para cada perfil de workload. + +**Desventaja:** los nodos no se pueden compartir entre proyectos. Cuando el pool de un proyecto está subutilizado, esa capacidad disponible no puede ser aprovechada por otros proyectos, lo que resulta en costos de infraestructura más altos en comparación con un enfoque de pools compartidos. + +:::tip +Este patrón es ideal cuando el aislamiento estricto es un requisito de negocio o compliance, o cuando los proyectos tienen perfiles de recursos muy distintos. Para la mayoría de los workloads, un conjunto reducido de pools compartidos es más eficiente en costos. +::: + --- ## Estrategias de Rendimiento diff --git a/content/tutorials/es/optimize-aws-costs.mdx b/content/tutorials/es/optimize-aws-costs.mdx index fb38b453a9..8849e73c9c 100644 --- a/content/tutorials/es/optimize-aws-costs.mdx +++ b/content/tutorials/es/optimize-aws-costs.mdx @@ -15,6 +15,8 @@ import { FiExternalLink } from "react-icons/fi"; Técnicas prácticas para reducir costos en AWS sin sacrificar confiabilidad — cubriendo cómputo, almacenamiento, CDN y estrategias de right-sizing. +¿Todavía no revisaste a dónde va tu gasto? Empezá por la [Guía de revisión de costos](/tutorial/cost-review-guide) para leer tus dashboards de Cost Explorer y Kubecost primero. + ## 1. Spot Instances con Auto Scaling — Reducir Costos EC2 Significativamente Correr todos los workloads en instancias EC2 On-Demand es caro. Mover workloads sin estado o tolerantes a fallos a **Spot Instances** respaldadas por un **Auto Scaling Group (ASG)** con fallback a On-Demand puede reducir esos costos sustancialmente. diff --git a/content/tutorials/es/postgresql-dump-restore.mdx b/content/tutorials/es/postgresql-dump-restore.mdx index d71fdcc44b..f270f2ab28 100644 --- a/content/tutorials/es/postgresql-dump-restore.mdx +++ b/content/tutorials/es/postgresql-dump-restore.mdx @@ -40,7 +40,7 @@ Ejecutá este comando desde cualquier máquina con acceso de red a la base de da pg_dump -h POSTGRESQL_ADDRESS -U POSTGRESQL_USERNAME -W -Fc -f dump.dump ``` -Para opciones detalladas, consultá la [documentación de la Dependency PostgreSQL de SleakOps](/docs/project/dependency/postgresql-aws#how-do-i-create-a-postgresql-database-dump). +Para opciones detalladas, consultá la [documentación de la Dependency PostgreSQL de SleakOps](/docs/project/dependency/postgresql-aws#cómo-puedo-crear-un-backup-dump-de-mi-base-de-datos-postgresql). ### Paso 2 — Escalar la instancia RDS destino diff --git a/content/tutorials/es/pritunl-dns-universal.mdx b/content/tutorials/es/pritunl-dns-universal.mdx index 8cb23df1fb..7c84655e54 100644 --- a/content/tutorials/es/pritunl-dns-universal.mdx +++ b/content/tutorials/es/pritunl-dns-universal.mdx @@ -243,3 +243,7 @@ chmod +x universal_fix_vpn_dns.sh :::warning Estos scripts **no** realizan cambios permanentes en el sistema. La configuración DNS desaparece automáticamente al desconectar la VPN. ::: + +## Ver también + +Si estás solucionando problemas específicamente en Lens (no podés conectarte a un cluster de SleakOps), consultá la guía [Solucionar problemas de conectividad al clúster con Lens](/tutorial/lens-cluster-connectivity) para verificaciones de VPN y pasos específicos de Lens. diff --git a/content/tutorials/es/rds-external-access.mdx b/content/tutorials/es/rds-external-access.mdx new file mode 100644 index 0000000000..1c8bde2711 --- /dev/null +++ b/content/tutorials/es/rds-external-access.mdx @@ -0,0 +1,35 @@ +--- +title: Encontrar el endpoint público de tu RDS +sidebar_label: Endpoint público de RDS +sidebar_position: 21 +description: Ubicá el endpoint de conexión de una réplica de lectura pública de RDS desde la consola de AWS. +tags: + - aws + - rds + - database + - networking +--- + +import { FiExternalLink } from "react-icons/fi"; + +Una vez que SleakOps configuró una réplica de lectura pública para tu instancia de RDS, podés encontrar su endpoint de conexión directamente en la consola de AWS. + +## Encontrar el endpoint + +1. Abrí la [consola de AWS ](https://console.aws.amazon.com/) y navegá a **RDS**. +2. En la barra lateral izquierda, hacé clic en **Databases**. +3. Buscá y hacé clic en tu instancia de DB o réplica de lectura. Las réplicas públicas suelen tener un sufijo como `-replica` o similar. +4. Abrí la pestaña **Connectivity & security**. +5. Copiá el valor de **Endpoint** — este es el hostname al que se conectará tu aplicación o cliente. + +El endpoint sigue el formato estándar de AWS RDS: + +``` +..rds.amazonaws.com +``` + +Usalo junto con el puerto de tu motor (por defecto `5432` para PostgreSQL, `3306` para MySQL y MariaDB, `1521` para Oracle, `1433` para SQL Server; Aurora usa `5432` o `3306` según el motor compatible) para configurar tu cliente de base de datos o cadena de conexión. + +:::warning +Las instancias de RDS públicas son accesibles desde internet. Verificá siempre que el Security Group asociado restrinja el acceso entrante únicamente a los rangos de IP que lo necesiten. +::: diff --git a/content/tutorials/es/sticky-sessions.mdx b/content/tutorials/es/sticky-sessions.mdx new file mode 100644 index 0000000000..8eff1ae376 --- /dev/null +++ b/content/tutorials/es/sticky-sessions.mdx @@ -0,0 +1,146 @@ +--- +title: Configurar sticky sessions +sidebar_label: Sticky Sessions +sidebar_position: 49 +description: Fijá cada cliente a la misma réplica de tu Web Service habilitando stickiness por cookie en el ALB desde las anotaciones del ingress. +tags: + - networking + - kubernetes + - aws + - scaling + - performance +image: /img/tutorials/sticky-sessions/connection-settings-advanced.png +--- + +import Zoom from "react-medium-image-zoom"; +import "react-medium-image-zoom/dist/styles.css"; +import { FiExternalLink } from "react-icons/fi"; + +Fijá cada cliente a la misma réplica de tu Web Service habilitando stickiness por cookie en el ALB desde las anotaciones del ingress. + +## Cuándo necesitás sticky sessions (y cuándo no) + +Todo Web Service con más de una réplica balancea el tráfico entre sus Pods, así que dos requests consecutivos del mismo navegador pueden caer en Pods distintos. Si tu aplicación guarda estado de sesión en memoria —un login, un carrito, una subida en curso— esos requests se rompen. + +La stickiness hace que el load balancer devuelva al cliente al Pod que ya venía usando. Es un parche útil, pero no resuelve el estado en memoria: + +- La afinidad muere con el Pod. Cada deploy reemplaza todos los Pods y cada scale-in elimina algunos, así que los clientes con cookie se reasignan y pierden la sesión igual. +- Un Pod puede quedarse con una porción desproporcionada de clientes de larga duración, lo que juega en contra del autoscaling. + +La solución de fondo es mover el estado de sesión a un backend compartido —una [Dependency de Redis](/docs/project/dependency/redis-aws) o tu base de datos— para que cualquier réplica pueda atender cualquier request. La [guía de testing de Environments](/tutorial/environment-exhaustive-testing-guide) incluye un test para exactamente esta falla. Usá stickiness cuando no podés cambiar la aplicación, o como puente mientras externalizás la sesión. + +## Prerrequisitos + +- Cuenta en SleakOps +- Un Cluster configurado ([documentación de Cluster](/docs/cluster)) +- Un Environment configurado ([documentación de Environment](/docs/environment)) +- Un Web Service con service schema `public` o `private`. Los services `internal` no tienen Ingress, así que la stickiness no aplica. +- Un rol distinto de **Viewer** — los Viewers no pueden editar la configuración de un Workload. + +## Empecemos + +SleakOps expone los Web Services a través de un Application Load Balancer de AWS, y la stickiness es un atributo del target group de ese load balancer. Se habilita agregando una anotación al Ingress que SleakOps genera para tu Web Service. + +### Agregá la anotación de stickiness + +1. Abrí tu Web Service desde **Workloads > Web Services**. +2. En la sección **Connection Settings**, hacé clic en **Edit Ingress**. +3. En la tabla Key/Value del final del diálogo, agregá este par: + +| **Campo** | **Valor** | +| --------- | ----------------------------------------------------------------------------------------- | +| **Key** | `alb.ingress.kubernetes.io/target-group-attributes` | +| **Value** | `stickiness.enabled=true,stickiness.type=lb_cookie,stickiness.lb_cookie.duration_seconds=86400` | + +4. Dejá **Deploy?** activado y hacé clic en **Update ingress config**. La anotación llega al cluster en el próximo deploy. + + + Diálogo IngressConfig con la anotación target-group-attributes en la tabla de Extra Annotations, ALB default annotations habilitado y Deploy? activado + + +Todos los demás campos quedan en su default: lo único que agregás es la fila de la anotación. + +:::warning Dejá ALB default annotations activado +El mismo diálogo tiene un switch **ALB default annotations**. Dejalo prendido: genera las anotaciones que el Ingress necesita para funcionar —`target-type: ip`, el nombre del grupo del load balancer y la configuración de los health checks—. Tus anotaciones extra se mergean por encima de esas, así que no hay motivo para desactivarlo. +::: + +El `target-type: ip` que SleakOps pone por defecto es además un requisito de la stickiness del ALB, y es lo que la hace útil acá: el load balancer registra IPs de Pod como targets, así que la cookie fija al cliente a un Pod puntual y no a un Node. + +### Configuralo desde el formulario del Web Service + +El mismo campo está disponible en el formulario del Web Service, tanto al crear el Workload como al editarlo. En el paso **Connection Settings**, expandí la sección **Advanced** y completá **Extra Annotations** dentro de **Ingress Annotations**. La anotación se aplica a todos los hosts del Web Service: su URL por defecto y cualquier Domain propio que apunte a él. + + + Paso Connection Settings del formulario del Web Service con la sección Advanced expandida, mostrando el bloque Ingress Annotations + + +### Ajustá la cookie + +El valor de la anotación es una lista de atributos del target group separados por comas. Reemplaza el conjunto completo de atributos de stickiness, así que mandá todos los pares que necesitás en un único valor. + +| **Atributo** | **Descripción** | **Default** | +| ---------------------------------------- | -------------------------------------------------------------------------------- | ----------------- | +| **stickiness.enabled** | Habilita la stickiness. `true` o `false`. | `false` | +| **stickiness.type** | `lb_cookie` para una cookie que genera el load balancer, `app_cookie` para seguir una que setea tu aplicación. | — | +| **stickiness.lb_cookie.duration_seconds** | Cuánto dura la afinidad con `lb_cookie`. De 1 segundo a 604800 (7 días). | `86400` (1 día) | +| **stickiness.app_cookie.cookie_name** | Nombre de la cookie de tu aplicación. Obligatorio con `app_cookie`. | — | +| **stickiness.app_cookie.duration_seconds** | Cuánto dura la afinidad con `app_cookie`. De 1 segundo a 604800 (7 días). | `86400` (1 día) | + +Con `app_cookie`, el nombre de la cookie no puede empezar con `AWSALB`, `AWSALBAPP` ni `AWSALBTG`: esos prefijos están reservados por el load balancer. + +Por ejemplo, una afinidad de dos horas manejada por tu propia cookie `JSESSIONID`: + +``` +stickiness.enabled=true,stickiness.type=app_cookie,stickiness.app_cookie.cookie_name=JSESSIONID,stickiness.app_cookie.duration_seconds=7200 +``` + +Mirá la [documentación de sticky sessions del ALB ](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/sticky-sessions.html) para el comportamiento completo de cada modo. + +### Verificalo + +Cuando termine el deploy, verificalo de punta a punta: + +**1. El load balancer setea la cookie.** Pedí tu service y mirá los headers de respuesta: + +```bash +curl -sI https://myservice.myenv.sleakops.com | grep -i set-cookie +``` + +Con `lb_cookie` vas a ver dos cookies: `AWSALB`, y una segunda `AWSALBCORS` con la misma información más el atributo `SameSite` que algunos navegadores exigen para requests cross-origin. El load balancer manda siempre las dos, tanto en respuestas CORS como no-CORS. + +Con `app_cookie` también son dos: la que setea tu aplicación y `AWSALBAPP-0` que genera el load balancer. Las cookies de más de 4 KB se fragmentan en más partes —`AWSALBAPP-1` y siguientes, hasta un máximo de cuatro fragmentos y 16 KB en total. + +Si no aparece ninguna, la anotación no llegó al Ingress: volvé al primer paso y confirmá que el deploy terminó. + +**2. Responde siempre el mismo Pod.** Guardá las cookies y reusalas: + +```bash +curl -s -c cookies.txt https://myservice.myenv.sleakops.com > /dev/null +for i in $(seq 1 10); do curl -s -b cookies.txt https://myservice.myenv.sleakops.com/tu-path-de-debug; done +``` + +Si tu aplicación expone su hostname en algún lado —la variable de entorno `HOSTNAME` dentro de un Pod es el nombre del Pod— todas las respuestas tendrían que reportar el mismo. Si no, abrí los logs del Web Service en [Headlamp](/docs/cluster/addons/headlamp) y confirmá que un solo Pod registra esos requests. + +**3. La anotación está en el objeto real.** Si alguno de los dos chequeos anteriores falla, abrí el Ingress del Namespace de tu Environment en Headlamp y confirmá que `alb.ingress.kubernetes.io/target-group-attributes` aparezca en sus anotaciones con el valor que cargaste. Si no está, el deploy no pasó; si está, el problema es más abajo — verificá que tu Web Service tenga más de una réplica. + +## Limitaciones + +:::warning +- **La afinidad no sobrevive al reemplazo de un Pod.** Los deploys, el scale-in y la consolidación de Nodes reasignan clientes. La stickiness reduce con qué frecuencia un cliente cambia de Pod; nunca garantiza que no pase. +- **No reemplaza el estado de sesión compartido.** Si perder una sesión es inaceptable, guardala en Redis o en tu base de datos. +- **El `sessionAffinity: ClientIP` de Kubernetes no tiene efecto acá.** El load balancer manda el tráfico directo a las IPs de los Pods, salteando el balanceo del propio Service, así que la afinidad se configura en el load balancer. +- **`ssl-redirect` y `listen-ports` no se pueden sobrescribir** desde Extra Annotations en los hosts servidos por HTTPS: SleakOps los fija al final para los hosts con TLS. +- **Los Web Services `internal` no tienen Ingress**, así que no hay nada que anotar. +::: + +## Próximos pasos + +- [Configuración de Web Service](/docs/project/workload/webservice) — el resto de las opciones del Workload, incluidas réplicas y autoscaling +- [Manifests](/docs/project/manifests) — editá directamente el YAML del Ingress generado cuando una anotación no alcanza +- [Values](/docs/project/values) — sobrescribí cualquier value generado de Helm, incluidas las opciones de ingress por host diff --git a/docusaurus.config.js b/docusaurus.config.js index 9552263d62..97a1b2428c 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -253,11 +253,11 @@ const config = { items: [ { label: "Terms & Conditions", - href: "https://craftech.notion.site/Terms-Conditions-efb8d9a980654625af456732ed44b197", + to: "/legal/terms-and-conditions", }, { label: "Privacy Policy", - href: "https://craftech.notion.site/Privacy-Policy-of-SleakOps-55b977da50d84871809879d065b16b3b", + to: "/legal/privacy-policy", }, ], }, diff --git a/package.json b/package.json index dd24aa383f..b1acddf862 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "clsx": "^1.2.1", "docusaurus-lunr-search": "^3.6.0", "gray-matter": "^4.0.3", - "joi": "^17.4.0", + "joi": "^17.13.4", "memfs": "^4.0.0", "prism-react-renderer": "^1.3.5", "react": "^18.0.0", diff --git a/src/data/tutorials-generated.json b/src/data/tutorials-generated.json index db647b5006..5a008d8a95 100644 --- a/src/data/tutorials-generated.json +++ b/src/data/tutorials-generated.json @@ -34,9 +34,16 @@ }, { "id": "environment-exhaustive-testing-guide", - "title": "Exhautive testing guide", - "description": "How can I thoroughly test my application to validate an environment?", - "tags": [], + "title": "Exhaustive Environment Testing Guide", + "description": "A comprehensive checklist of tests to validate that your application is fully functional after migrating to a new SleakOps infrastructure.", + "tags": [ + "kubernetes", + "aws", + "performance", + "security", + "monitoring", + "deployment" + ], "image": null, "sidebar_position": 4 }, @@ -248,19 +255,6 @@ "image": "/img/tutorials/postgres-helm-existing-volume/postgres-helm-existing-volume.png", "sidebar_position": 16 }, - { - "id": "migrate-external-s3", - "title": "Migrate an External S3 Bucket to SleakOps", - "description": "Copy objects from a source S3 bucket in an external AWS account to a SleakOps-managed S3 bucket using cross-account bucket policies and aws s3 sync.", - "tags": [ - "aws", - "s3", - "migration", - "storage" - ], - "image": "/img/tutorials/migrate-external-s3/migrate-external-s3.png", - "sidebar_position": 17 - }, { "id": "migrate-files-volumes-copy", "title": "Migrate Files Between Kubernetes Volumes Using kubectl cp", @@ -302,17 +296,15 @@ }, { "id": "rds-external-access", - "title": "Access an RDS Instance from Outside Your VPC", - "description": "Options to securely access an Amazon RDS instance running in a private subnet from outside the VPC — Bastion Host, AWS Client VPN, PrivateLink, and public access.", + "title": "Find Your Public RDS Endpoint", + "description": "Locate the connection endpoint of a public RDS read replica from the AWS Console.", "tags": [ "aws", "rds", "database", - "networking", - "security", - "vpn" + "networking" ], - "image": "/img/tutorials/rds-external-access/rds-external-access.png", + "image": null, "sidebar_position": 21 }, { @@ -457,29 +449,29 @@ "sidebar_position": 32 }, { - "id": "deploy-datadog-operator", - "title": "Deploy Datadog Operator and DatadogAgent on SleakOps", - "description": "Install the Datadog Operator (v2.8.0) and deploy a DatadogAgent (v7.63.3) on a SleakOps EKS cluster with Karpenter NodePool tolerations, APM, log collection, and admission controller.", + "id": "install-datadog", + "title": "Install Datadog on a SleakOps EKS Cluster", + "description": "Install the Datadog monitoring agent on an Amazon EKS cluster managed by SleakOps using Helm, with a values.yaml and recommended best practices.", "tags": [ "kubernetes", "monitoring", - "deployment", - "helm" + "helm", + "aws" ], - "image": "/img/tutorials/deploy-datadog-operator/deploy-datadog-operator.png", + "image": "/img/tutorials/install-datadog/install-datadog.png", "sidebar_position": 33 }, { - "id": "install-datadog", - "title": "Install Datadog on a SleakOps EKS Cluster", - "description": "Install the Datadog monitoring agent on an Amazon EKS cluster managed by SleakOps using Helm, with a values.yaml and recommended best practices.", + "id": "deploy-datadog-operator", + "title": "Deploy Datadog Operator and DatadogAgent on SleakOps", + "description": "Install the Datadog Operator (v2.8.0) and deploy a DatadogAgent (v7.63.3) on a SleakOps EKS cluster with Karpenter NodePool tolerations, APM, log collection, and admission controller.", "tags": [ "kubernetes", "monitoring", - "helm", - "aws" + "deployment", + "helm" ], - "image": "/img/tutorials/install-datadog/install-datadog.png", + "image": "/img/tutorials/deploy-datadog-operator/deploy-datadog-operator.png", "sidebar_position": 34 }, { @@ -529,6 +521,8 @@ ], "image": "/img/tutorials/optimize-docker-image/optimize-docker-image.png", "sidebar_position": 42 + }, + { "id": "nodepool-strategies", "title": "Nodepool Strategies in SleakOps", "description": "Learn how to configure nodepools in SleakOps to optimize costs, improve performance, and choose the right instance types for each workload.", @@ -541,6 +535,33 @@ ], "image": "/img/tutorials/nodepool-strategies/nodepool-strategies.png", "sidebar_position": 47 + }, + { + "id": "cost-review-guide", + "title": "How to Review Your SleakOps Costs", + "description": "A practical walkthrough of the SleakOps Cost Explorer, Kubecost, and Cost Allocation Tags — how to read what you're already spending before deciding what to optimize.", + "tags": [ + "billing", + "cost-analysis", + "kubecost", + "monitoring" + ], + "image": "/img/tutorials/cost-review-guide/cost-explorer-dashboard.png", + "sidebar_position": 48 + }, + { + "id": "sticky-sessions", + "title": "Configure Sticky Sessions", + "description": "Pin each client to the same Web Service replica by enabling ALB cookie stickiness from the ingress annotations.", + "tags": [ + "networking", + "kubernetes", + "aws", + "scaling", + "performance" + ], + "image": "/img/tutorials/sticky-sessions/connection-settings-advanced.png", + "sidebar_position": 49 } ], "es": [ @@ -578,9 +599,16 @@ }, { "id": "environment-exhaustive-testing-guide", - "title": "¿Cómo probar exhaustivametne mi aplicación para validar un ambiente?", - "description": "¿Cómo probar exhaustivametne mi aplicación para validar un ambiente?", - "tags": [], + "title": "Guía de pruebas exhaustivas para validar un ambiente", + "description": "Un checklist completo de pruebas para validar que tu aplicación funciona correctamente después de migrar a una nueva infraestructura en SleakOps.", + "tags": [ + "kubernetes", + "aws", + "performance", + "security", + "monitoring", + "deployment" + ], "image": null, "sidebar_position": 4 }, @@ -792,19 +820,6 @@ "image": "/img/tutorials/postgres-helm-existing-volume/postgres-helm-existing-volume.png", "sidebar_position": 16 }, - { - "id": "migrate-external-s3", - "title": "Migrar un bucket S3 externo a SleakOps", - "description": "Copiá objetos desde un bucket S3 en una cuenta AWS externa a un bucket S3 administrado por SleakOps usando políticas de bucket cross-account y aws s3 sync.", - "tags": [ - "aws", - "s3", - "migration", - "storage" - ], - "image": "/img/tutorials/migrate-external-s3/migrate-external-s3.png", - "sidebar_position": 17 - }, { "id": "migrate-files-volumes-copy", "title": "Migrar archivos entre volúmenes de Kubernetes con kubectl cp", @@ -846,17 +861,15 @@ }, { "id": "rds-external-access", - "title": "Acceder a una instancia RDS desde fuera de tu VPC", - "description": "Opciones para acceder de forma segura a una instancia de Amazon RDS en una subnet privada desde fuera de la VPC — Bastion Host, AWS Client VPN, PrivateLink y acceso público.", + "title": "Encontrar el endpoint público de tu RDS", + "description": "Ubicá el endpoint de conexión de una réplica de lectura pública de RDS desde la consola de AWS.", "tags": [ "aws", "rds", "database", - "networking", - "security", - "vpn" + "networking" ], - "image": "/img/tutorials/rds-external-access/rds-external-access.png", + "image": null, "sidebar_position": 21 }, { @@ -1001,29 +1014,29 @@ "sidebar_position": 32 }, { - "id": "deploy-datadog-operator", - "title": "Desplegar Datadog Operator y DatadogAgent en SleakOps", - "description": "Instalá el Datadog Operator (v2.8.0) y desplegá un DatadogAgent (v7.63.3) en un cluster EKS de SleakOps con toleraciones de NodePool Karpenter, APM, recolección de logs y admission controller.", + "id": "install-datadog", + "title": "Instalar Datadog en un Cluster EKS de SleakOps", + "description": "Instalá el agente de monitoreo Datadog en un cluster Amazon EKS gestionado por SleakOps usando Helm, con un values.yaml y buenas prácticas recomendadas.", "tags": [ "kubernetes", "monitoring", - "deployment", - "helm" + "helm", + "aws" ], - "image": "/img/tutorials/deploy-datadog-operator/deploy-datadog-operator.png", + "image": "/img/tutorials/install-datadog/install-datadog.png", "sidebar_position": 33 }, { - "id": "install-datadog", - "title": "Instalar Datadog en un Cluster EKS de SleakOps", - "description": "Instalá el agente de monitoreo Datadog en un cluster Amazon EKS gestionado por SleakOps usando Helm, con un values.yaml y buenas prácticas recomendadas.", + "id": "deploy-datadog-operator", + "title": "Desplegar Datadog Operator y DatadogAgent en SleakOps", + "description": "Instalá el Datadog Operator (v2.8.0) y desplegá un DatadogAgent (v7.63.3) en un cluster EKS de SleakOps con toleraciones de NodePool Karpenter, APM, recolección de logs y admission controller.", "tags": [ "kubernetes", "monitoring", - "helm", - "aws" + "deployment", + "helm" ], - "image": "/img/tutorials/install-datadog/install-datadog.png", + "image": "/img/tutorials/deploy-datadog-operator/deploy-datadog-operator.png", "sidebar_position": 34 }, { @@ -1073,6 +1086,8 @@ ], "image": "/img/tutorials/optimize-docker-image/optimize-docker-image.png", "sidebar_position": 42 + }, + { "id": "nodepool-strategies", "title": "Estrategias de Nodepools en SleakOps", "description": "Aprendé a configurar nodepools en SleakOps para optimizar costos, mejorar el rendimiento y elegir los tipos de instancia correctos para cada workload.", @@ -1085,6 +1100,33 @@ ], "image": "/img/tutorials/nodepool-strategies/nodepool-strategies.png", "sidebar_position": 47 + }, + { + "id": "cost-review-guide", + "title": "Cómo revisar tus costos en SleakOps", + "description": "Un recorrido práctico por el Cost Explorer de SleakOps, Kubecost y las Cost Allocation Tags — cómo leer lo que ya estás gastando antes de decidir qué optimizar.", + "tags": [ + "billing", + "cost-analysis", + "kubecost", + "monitoring" + ], + "image": "/img/tutorials/cost-review-guide/cost-explorer-dashboard.png", + "sidebar_position": 48 + }, + { + "id": "sticky-sessions", + "title": "Configurar sticky sessions", + "description": "Fijá cada cliente a la misma réplica de tu Web Service habilitando stickiness por cookie en el ALB desde las anotaciones del ingress.", + "tags": [ + "networking", + "kubernetes", + "aws", + "scaling", + "performance" + ], + "image": "/img/tutorials/sticky-sessions/connection-settings-advanced.png", + "sidebar_position": 49 } ] -} +} \ No newline at end of file diff --git a/src/pages/legal/privacy-policy.md b/src/pages/legal/privacy-policy.md new file mode 100644 index 0000000000..0fd1ecaaee --- /dev/null +++ b/src/pages/legal/privacy-policy.md @@ -0,0 +1,181 @@ +--- +title: Privacy Policy +--- + +# Privacy Policy of SleakOps + +**Last Updated:** May 15th, 2024 + +Welcome to SleakOps, operated by Craftech-io, Inc. ("us", "we", or "our"). Our service, accessible from [www.sleakops.com](https://www.sleakops.com/) ("Service"), is committed to protecting your privacy. This Privacy Policy outlines our practices regarding the collection, use, and disclosure of your information through your use of our Service and applies to all visitors, users, and others who access the Service. + +By using our Service, you agree to the collection and use of information in accordance with this policy. + +## Information Collection and Use + +We collect several types of information for various purposes to provide and improve our Service. + +### Types of Data Collected: + +### Personal Data + +While using our Service, we may ask you to provide us with certain personally identifiable information that can be used to contact or identify you ("Personal Data"). Personal Data may include, but is not limited to: + +- Email address +- First name and last name +- Phone number +- Address, State, Province, ZIP/Postal code, City +- Cookies and Usage Data + +This information enables us to provide you with a personalized experience, effectively respond to your requests, and improve our services. + +### Usage Data + +Usage Data is automatically collected when using the Service. This data may include details such as: + +- Your Device's Internet Protocol address (e.g., IP address) +- Browser type and version +- Pages of our Service that you visit +- Time and date of your visit +- Time spent on those pages +- Unique device identifiers and other diagnostic data + +### Tracking & Cookies Data + +We use Cookies and similar tracking technologies to track activity on our Service and store certain information. These technologies are used to enhance the efficiency and user-friendliness of our services; they enable us to improve our Service and your experience by allowing us to: + +- Remember your login details +- Provide personalized content +- Analyze how our Service is used +- Types of cookies used may include: + +**Session Cookies:** Necessary for the proper functioning of our Service, such as enabling you to log into secure areas. + +**Preference Cookies:** Allow us to remember your preferences and various settings. + +**Security Cookies:** Help us to ensure the security of your account. + +**Analytics Cookies and Beacons:** Used to gather aggregated data about website traffic and how users interact with our website, enabling us to improve our Service and tailor it more to your needs. + +By using the Service, you consent to the use of these technologies as described in our Cookies Policy. You have the option to refuse all cookies or to indicate when a cookie is being sent. However, if you do not accept cookies, you may not be able to use some parts of our Service. + +## Use of Data + +We use your personal data to operate and manage our Service. This includes using your information to: + +- Register and manage your account. +- Provide the services you request. +- Communicate with you about your account or services you use. + +### Communication + +We use your personal data to contact you about updates, service changes, and promotional offers, if you have opted to receive these communications. This may include: + +- Emails about service updates or changes. +- Promotional emails, if you have agreed to receive them. + +### Service Improvement + +We analyze how you use our services to help us improve and develop these services, and to enhance your overall experience. This involves: + +- Analyzing usage patterns to identify improvements. +- Testing new features. + +### Compliance and Enforcement + +We use your data to comply with legal obligations and enforce our terms, including: + +- Responding to legal requests or preventing fraud. +- Ensuring the security of our services. + +### Sharing Your Data + +We may share your data with: + +- Service providers who assist us with parts of our business operations. +- Legal authorities when required by law. +- Other parties in connection with a business transaction like a merger or sale. + +## Transfer of Data + +Your information, including Personal Data, may be transferred to — and maintained on — computers located outside of your state, province, country, or other governmental jurisdiction where the data protection laws may differ from those in your jurisdiction. + +Your consent to this Privacy Policy followed by your submission of such information represents your agreement to that transfer. + +We will take all the steps reasonably necessary to ensure that your data is treated securely and in accordance with this Privacy Policy and no transfer of your Personal Data will take place to an organization or a country unless there are adequate controls in place including the security of your data and other personal information. + +## Disclosure of Data + +We may disclose your Personal Data in the good faith belief that such action is necessary to: + +### Business Transactions + +If the Company is involved in a merger, acquisition or asset sale, Your Personal Data may be transferred. We will provide notice before Your Personal Data is transferred and becomes subject to a different Privacy Policy. + +### Law enforcement + +Under certain circumstances, the Company may be required to disclose Your Personal Data if required to do so by law or in response to valid requests by public authorities (e.g. a court or a government agency). + +### Other legal requirements + +The Company may disclose Your Personal Data in the good faith belief that such action is necessary to: + +- Comply with a legal obligation +- Protect and defend the rights or property of the Company +- Prevent or investigate possible wrongdoing in connection with the Service +- Protect the personal safety of Users of the Service or the public +- Protect against legal liability + +## Security of Data + +The security of your data is important to us but remember that no method of transmission over the Internet or method of electronic storage is 100% secure. We cannot guarantee its absolute security. + +## Service Providers + +We may employ third-party companies and individuals to facilitate our Service ("Service Providers"), to provide the Service on our behalf, to perform Service-related services, or to assist us in analyzing how our Service is used. + +These third parties have access to your Personal Data only to perform these tasks on our behalf and are obligated not to disclose or use it for any other purpose. + +### CI/CD Tools + +We may use third-party Service Providers to automate the development process of our Service. + +GitLab CI/CD is provided by GitLab, Inc.: + +- GitLab CI (Continuous Integration) service is a part of GitLab that build and test the software whenever developer pushes code to application. +- GitLab CD (Continuous Deployment) is a software service that places the changes of every code in the production which results in every day deployment of production. + +For more information on what data GitLab CI/CD collects for what purpose and how the protection of the data is ensured, please visit GitLab CI/CD Privacy Policy page: https://about.gitlab.com/privacy/. + +### Payments + +We may provide paid products and/or services within Service. In that case, we use third-party services for payment processing (e.g. payment processors). + +We will not store or collect your payment card details. That information is provided directly to our third-party payment processors whose use of your personal information is governed by their Privacy Policy. + +These payment processors adhere to the standards set by PCI-DSS as managed by the PCI Security Standards Council, which is a joint effort of brands like Visa, Mastercard, American Express and Discover. PCI-DSS requirements help ensure the secure handling of payment information. + +The payment processors we work with are: + +- Stripe: Their Privacy Policy can be viewed at https://stripe.com/us/privacy + +## Links to Other Websites + +Our Service may contain links to third-party websites or services that are not owned or controlled by Craftech-io, Inc. + +We have no control over, and assume no responsibility for, the content, privacy policies, or practices of any third-party websites or services. + +We strongly advise you to read the terms and conditions and privacy policies of any third-party websites or services that you visit. + +## Age Restrictions + +Our Service addresses only for those who are at least 18 years of age. If you are under 18, do not use the Service. + +## Changes to Privacy Policy + +We reserve the right, at our sole discretion, to modify or replace this Privacy Policy at any time. It is your responsibility to review this Privacy Policy periodically. + +By continuing to access or use our Service after those revisions become effective, you agree to be bound by the revised Privacy Policy. + +## Contact Us + +If you have any questions about this Privacy Policy, please contact us: contact@sleakops.com diff --git a/src/pages/legal/terms-and-conditions.md b/src/pages/legal/terms-and-conditions.md new file mode 100644 index 0000000000..b613b34dca --- /dev/null +++ b/src/pages/legal/terms-and-conditions.md @@ -0,0 +1,211 @@ +--- +title: Terms & Conditions +--- + +# Terms & Conditions + +**Last Updated:** May 15th, 2024 + +## Introduction + +Welcome to [www.sleakops.com](http://www.sleakops.com/) ("Website"), a service provided by Craftech-io, Inc. ("Company", "we", "us", or "our"). The Company is headquartered at 651 North Broad Street, Middletown, Delaware, USA. + +These Terms and Conditions ("Terms") govern your access to and use of our Website and its associated services (collectively, "Service"). By accessing or using any part of our Service, you ("User", "you") agree to be bound by these Terms and our [Privacy Policy](/legal/privacy-policy). If you do not agree to all the terms and conditions of this agreement, then you may not access the Website or use any services. + +Please read these Terms carefully before accessing our Service. These Terms apply to all visitors, users, and others who access or use the Service. By agreeing to these Terms, you represent that you are at least 18 years old or of legal age to form a binding contract under applicable laws. If you are accessing and using the Service on behalf of a company, organization, or other legal entity, you represent and warrant that you have the authority to bind such entity to these Terms, in which case the terms "User", "you", or "your" shall refer to such entity. + +Your access to and use of the Service is conditioned on your acceptance of and compliance with these Terms. These Terms are important and affect your legal rights, so please read them carefully. + +## Communications + +By creating an Account on our Service, you agree to subscribe to newsletters, marketing or promotional materials and other information we may send. However, you can cancel these communications by following the unsubscribe link or by emailing [contact@sleakops.com](mailto:contact@sleakops.com). + +## Account Responsibilities + +You must register for an account to access and use certain features of our Service. By creating an account, you agree to: + +- Provide accurate, complete, and up-to-date information as requested on the registration form. +- Update your information to maintain its accuracy and completeness. +- Accept all risks associated with unauthorized access to your account resulting from your action or inaction. + +### Account Security + +You are responsible for safeguarding the password you use to access our Service and for any activities or actions under your account, whether your password is with our Service or a third-party service. You agree to: + +- Keep your password secure and confidential. +- Notify us immediately upon becoming aware of any breach of security or unauthorized use of your account. +- Not disclose your password to any third party. +- Your account is personal to you and you may not transfer or make available your account to others. You are responsible for all activities that occur under your account, whether or not you know about them. + +### Account Restrictions + +You must not use another user's account or registration information for our Service without permission. Similarly, you may not permit anyone else to use your account. You may not use your account to engage in any unlawful activity or fraudulent purpose or to infringe on the rights of others. + +### Termination and Suspension + +We reserve the right to suspend or terminate your account, refuse any and all current or future use of our Service, and not provide any services to you if: + +- You breach any term of these Terms and Conditions. +- We are unable to verify or authenticate any information you provide to us. +- We believe that your actions may cause legal liability for you, our users, or us. +- You are responsible for any content that you create, transmit, or display while using our Service and for the consequences of your actions by doing so. + +Upon termination, your right to use the Service will cease immediately, and any data or content stored in your account may be inaccessible. + +## Purchases + +When you wish to purchase any service made available, you may be asked to supply certain information relevant to your Purchase, including, without limitation, your credit card number, the expiration date of your credit card, your billing address, and other payment information. + +All services listed are subject to acceptance and availability. We may refuse or be unable to process your booking if: + +- The service you selected is no longer available. +- There is an error in the price or description of the service. + +You represent and warrant that: + +- You have the legal right to use any credit card(s) or other payment method(s) in connection with any Purchase. +- The information you supply to us is true, correct, and complete. + +## Subscriptions + +Details of the different subscription types, services included, and pricing are available on our Website and on AWS Platform. You can select the subscription that best fits your needs. + +### Subscription Enrollment via AWS Marketplace + +Subscription to the SleakOps platform is facilitated through the AWS (Amazon Web Services) Marketplace. By subscribing, you agree to have AWS bill you for the use of SleakOps services. The subscription will automatically renew at the end of each billing period, unless you or SleakOps cancel the subscription. + +### Payment and Billing Information + +All billing for SleakOps services will be processed by AWS. Charges for our services will appear as a separate item on your AWS invoice. SleakOps is not responsible for billing or the specific transaction details managed through the AWS Marketplace. By providing a payment method accepted by AWS, you confirm that you are authorized to use the designated payment method and that you permit us to charge your payment method for the total amount of your subscription including any applicable taxes and other charges. + +### AWS Account Billing + +Services from SleakOps will appear as a separate charge on your AWS account invoice. We are not responsible for the billing or the specific details of the transactions conducted through the AWS Marketplace. + +### AWS Terms and Conditions + +By using SleakOps, you acknowledge that the platform utilizes AWS as its cloud service provider. Therefore, you also agree to abide by the AWS Terms and Conditions, which are incorporated by reference into these [Terms and Conditions of SleakOps](https://aws.amazon.com/legal/?nc1=f_cc). It is your responsibility to review and comply with AWS's Terms and Conditions. + +### Renewal and Cancellation + +You may cancel your subscription at any time either through your account settings on the SleakOps platform, via your AWS account settings, or by contacting us. Upon cancellation, your subscription will remain active until the end of the current billing period, but you will not be billed for the next period. You will not receive a refund for any remaining days in your current billing cycle. It's important to cancel your subscription before it renews if you do not wish to be charged for the next billing cycle. + +### Changes to Subscription Plans + +We reserve the right to modify, terminate, or otherwise amend our offered subscription plans. In the event of a plan modification, we will provide you with reasonable notice in advance via email or through a notice on our Website. If you do not agree with the changes, you may cancel your subscription as described above. + +### Free Trials + +We may offer a free trial period for a subscription to our services. Unless you cancel before the end of the trial period, the regular subscription fees will apply after the trial period ends. Details and conditions of any free trial will be communicated at the time of signing up. + +### Termination by Us + +We reserve the right to terminate your subscription if you fail to pay the subscription fees or otherwise comply with any of the terms of this Agreement. In such cases, you will not be entitled to any refund. + +## Content on the Platform + +Our Service allows you to post, link, store, share, and otherwise make available certain information, text, graphics, videos, or other materials ("Content"). You are fully responsible for the Content that you upload, share, or otherwise make available via the Service, including its legality, reliability, and appropriateness. + +By posting Content on or through the Service, you represent and warrant that: + +- The Content is yours, or you have the necessary rights to use it and grant us the rights and licenses as described in these Terms. +- The posting of your Content does not infringe on the privacy rights, publicity rights, copyrights, contractual rights, or any other rights of any person or entity. + +### Content Moderation + +SleakOps has the right, but not the obligation, to monitor and edit or remove any Content provided by users. We may remove or restrict access to any Content posted on or through the Service at any time and without notice if we believe it violates our policies or the law. We also reserve the right to terminate the account of anyone found to be infringing on a copyright. + +### Liability for Content + +You retain any and all of your rights to any Content you submit, post, or display on or through the Service and you are responsible for protecting those rights. We take no responsibility and assume no liability for Content you or any third party posts on or through the Service. + +## Prohibited Uses + +In using our Service, you are prohibited from engaging in the following activities: + +- Using the Service for any unlawful purposes or in furtherance of illegal activities. International users agree to comply with all local laws regarding online conduct and acceptable content. +- Posting or distributing content that infringes on any other intellectual property, privacy, or publicity right of another. +- Transmitting any viruses, malware, or other types of malicious software, or links to such software, through the Service. +- Engaging in activities that disrupt, undermine, or manipulate the integrity or functionality of any computer systems or networks used by SleakOps and its users. +- Using bots, spiders, or other automated methods to access the Service for any purpose without our express written permission. +- Bypassing the measures we may use to prevent or restrict access to the Service, including features that prevent or restrict use or copying of any content or enforce limitations on the use of the Service or the content therein. +- Attempting to interfere with, compromise the system integrity or security, or decipher any transmissions to or from the servers running the Service. +- Taking any action that imposes, or may impose at our sole discretion, an unreasonable or disproportionately large load on our infrastructure. + +### Unauthorized Commercial Activities and/or Sales + +- Using the Service for any commercial solicitation purposes, without prior written permission from SleakOps. +- Advertising or offering to sell or buy any goods or services for any business purpose that is not specifically authorized. + +### False Information + +Creating or operating a false identity on the Service, impersonating another person or entity, or falsifying your affiliation with a person or entity. + +### Harassment and Abuse + +- Engaging in any behavior that restricts or inhibits any other user from using or enjoying the Service, or that, as determined by us, may harm SleakOps or users of the Service or expose them to liability. +- Publishing or posting other people's private information without their express authorization and permission. + +### Copyright Infringement + +- Uploading, posting, hosting, or transmitting unsolicited email, SMSs, or "spam" messages. +- Uploading, posting, hosting, or transmitting any content that includes code that is hidden or otherwise surreptitiously contained within the content which is unrelated to the content. + +These activities are strictly forbidden and may result in immediate termination of your access to the Service, legal action against you, and potential civil and/or criminal penalties under applicable law. We reserve the right to investigate occurrences and prosecute any user or users who have participated in any such violations. + +## Analytics + +We may use third-party Service Providers to monitor and analyze the use of our Service. + +- New Relic +- Data Dog + +## Intellectual Property + +All content, features, and functionality of the Service, including text, graphics, logos, icons, images, audio clips, digital downloads, data compilations, and software, are the property of Craftech-io, Inc., its affiliates or its service providers, and are protected by international copyright and intellectual property laws. Unauthorized use may result in civil and criminal penalties. + +## Age Restrictions + +Our Service is intended only for those who are at least 18 years of age. If you are under 18, do not use the Service. + +## Links to Other Websites + +Our Service may contain links to third-party websites or services that are not owned or controlled by Craftech-io, Inc. + +We have no control over, and assume no responsibility for, the content, privacy policies, or practices of any third-party websites or services. + +We strongly advise you to read the terms and conditions and privacy policies of any third-party websites or services that you visit. + +## Termination + +We may terminate or suspend your access to our Service immediately, without prior notice or liability, for any reason whatsoever, including without limitation if you breach the Terms. Upon termination, your right to use the Service will cease immediately. If you wish to terminate your account, you may simply discontinue using the Service. + +## Governing Law + +These Terms shall be governed and construed in accordance with the laws of Delaware, United States, without regard to its conflict of law provisions. Our failure to enforce any right or provision of these Terms will not be considered a waiver of those rights. + +## Changes to Terms + +We reserve the right, at our sole discretion, to modify or replace these Terms at any time. It is your responsibility to review these Terms periodically. + +By continuing to access or use our Service after those revisions become effective, you agree to be bound by the revised terms. + +## Disclaimer and Limitation of Liability + +### Disclaimer of Warranties and Force Majeure + +In no event shall Craftech-io, Inc. or its suppliers be liable for any consequential loss suffered or incurred by you or any third party arising from the use or inability to use this Service, even if Craftech-io, Inc. or an authorized representative has been notified, orally or in writing, of the possibility of such damage. + +### "AS IS" and "AS AVAILABLE" Disclaimer + +The services provided by SleakOps.com are available "AS IS" and "AS AVAILABLE" without any warranties or guarantees, either expressed or implied. Craftech-io, Inc. disclaims all warranties, including but not limited to implied warranties of merchantability, fitness for a particular purpose, and non-infringement. + +We do not warrant that the service will be uninterrupted, timely, secure, or error-free, that defects will be corrected, or that the service or the server that makes it available are free of viruses or other harmful components. Use of our services is at your sole risk. + +### Force Majeure + +Craftech-io, Inc. shall not be liable for any failure to perform its obligations under these Terms where such failure results from any cause beyond Craftech-io, Inc.'s reasonable control, including, without limitation, mechanical, electronic, or communications failure or degradation, acts of God, natural disasters, pandemic or epidemic, terrorism, war, or any government restrictions. Such force majeure events may result in the Service being temporarily unavailable, and we commit to making all reasonable efforts to mitigate the situation and restore the Service as soon as possible. + +## Contact Us + +If you have any questions about these Terms, please contact us: [contact@sleakops.com](mailto:contact@sleakops.com) diff --git a/static/img/tutorials/cost-review-guide/cost-explorer-dashboard.png b/static/img/tutorials/cost-review-guide/cost-explorer-dashboard.png new file mode 100644 index 0000000000..320352ffda Binary files /dev/null and b/static/img/tutorials/cost-review-guide/cost-explorer-dashboard.png differ diff --git a/static/img/tutorials/cost-review-guide/cost-explorer-drilldown.png b/static/img/tutorials/cost-review-guide/cost-explorer-drilldown.png new file mode 100644 index 0000000000..bfa121f5fb Binary files /dev/null and b/static/img/tutorials/cost-review-guide/cost-explorer-drilldown.png differ diff --git a/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/atlas-connection-modal.png b/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/atlas-connection-modal.png new file mode 100644 index 0000000000..cb90aa155d Binary files /dev/null and b/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/atlas-connection-modal.png differ diff --git a/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/atlas-custom-dns.png b/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/atlas-custom-dns.png new file mode 100644 index 0000000000..0eb898a556 Binary files /dev/null and b/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/atlas-custom-dns.png differ diff --git a/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/atlas-network-access-peering.png b/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/atlas-network-access-peering.png new file mode 100644 index 0000000000..66a978b755 Binary files /dev/null and b/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/atlas-network-access-peering.png differ diff --git a/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/atlas-peering-available-1.png b/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/atlas-peering-available-1.png new file mode 100644 index 0000000000..991f2b31f9 Binary files /dev/null and b/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/atlas-peering-available-1.png differ diff --git a/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/atlas-peering-available-2.png b/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/atlas-peering-available-2.png new file mode 100644 index 0000000000..c2477eed39 Binary files /dev/null and b/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/atlas-peering-available-2.png differ diff --git a/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/atlas-peering-form.png b/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/atlas-peering-form.png new file mode 100644 index 0000000000..8e6582d759 Binary files /dev/null and b/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/atlas-peering-form.png differ diff --git a/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/atlas-peering-waiting.png b/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/atlas-peering-waiting.png new file mode 100644 index 0000000000..556e5cd12f Binary files /dev/null and b/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/atlas-peering-waiting.png differ diff --git a/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/atlas-private-connection-string.png b/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/atlas-private-connection-string.png new file mode 100644 index 0000000000..6553033739 Binary files /dev/null and b/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/atlas-private-connection-string.png differ diff --git a/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/aws-peering-accept-1.png b/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/aws-peering-accept-1.png new file mode 100644 index 0000000000..f43b816591 Binary files /dev/null and b/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/aws-peering-accept-1.png differ diff --git a/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/aws-peering-accept-2.png b/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/aws-peering-accept-2.png new file mode 100644 index 0000000000..7a413cc1cb Binary files /dev/null and b/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/aws-peering-accept-2.png differ diff --git a/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/aws-peering-pending-1.png b/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/aws-peering-pending-1.png new file mode 100644 index 0000000000..4321e75bd9 Binary files /dev/null and b/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/aws-peering-pending-1.png differ diff --git a/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/aws-peering-pending-2.png b/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/aws-peering-pending-2.png new file mode 100644 index 0000000000..af431ecd2d Binary files /dev/null and b/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/aws-peering-pending-2.png differ diff --git a/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/aws-route-table-edit.png b/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/aws-route-table-edit.png new file mode 100644 index 0000000000..f0b7479400 Binary files /dev/null and b/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/aws-route-table-edit.png differ diff --git a/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/aws-route-table.png b/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/aws-route-table.png new file mode 100644 index 0000000000..85b2ae14f2 Binary files /dev/null and b/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/aws-route-table.png differ diff --git a/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/pritunl-add-route.png b/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/pritunl-add-route.png new file mode 100644 index 0000000000..cef118a2b1 Binary files /dev/null and b/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/pritunl-add-route.png differ diff --git a/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/pritunl-route-saved.png b/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/pritunl-route-saved.png new file mode 100644 index 0000000000..079fe8a9ab Binary files /dev/null and b/static/img/tutorials/how-to-set-up-vpc-peering-between-aws-and-mongodb-atlas/pritunl-route-saved.png differ diff --git a/static/img/tutorials/sticky-sessions/connection-settings-advanced.png b/static/img/tutorials/sticky-sessions/connection-settings-advanced.png new file mode 100644 index 0000000000..58ba28b151 Binary files /dev/null and b/static/img/tutorials/sticky-sessions/connection-settings-advanced.png differ diff --git a/static/img/tutorials/sticky-sessions/ingress-config-dialog.png b/static/img/tutorials/sticky-sessions/ingress-config-dialog.png new file mode 100644 index 0000000000..1cc32e8285 Binary files /dev/null and b/static/img/tutorials/sticky-sessions/ingress-config-dialog.png differ diff --git a/sync_content.js b/sync_content.js index 775387ab6b..551fc9dfe1 100644 --- a/sync_content.js +++ b/sync_content.js @@ -57,6 +57,11 @@ const SYNC_MAP = [ dest: "i18n/es/docusaurus-plugin-content-blog-changelog", description: "Spanish changelog", }, + { + source: "content/pages/es", + dest: "i18n/es/docusaurus-plugin-content-pages", + description: "Spanish standalone pages", + }, ]; /** diff --git a/yarn.lock b/yarn.lock index a19594ef33..b76157dde1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -135,15 +135,6 @@ "@algolia/requester-fetch" "5.40.1" "@algolia/requester-node-http" "5.40.1" -"@algolia/client-search@^4.9.1", "@algolia/client-search@>= 4.9.1 < 6": - version "4.24.0" - resolved "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz" - integrity sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA== - dependencies: - "@algolia/client-common" "4.24.0" - "@algolia/requester-common" "4.24.0" - "@algolia/transporter" "4.24.0" - "@algolia/client-search@5.40.1": version "5.40.1" resolved "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.40.1.tgz" @@ -154,6 +145,15 @@ "@algolia/requester-fetch" "5.40.1" "@algolia/requester-node-http" "5.40.1" +"@algolia/client-search@^4.9.1": + version "4.24.0" + resolved "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz" + integrity sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA== + dependencies: + "@algolia/client-common" "4.24.0" + "@algolia/requester-common" "4.24.0" + "@algolia/transporter" "4.24.0" + "@algolia/events@^4.0.1": version "4.0.1" resolved "https://registry.npmjs.org/@algolia/events/-/events-4.0.1.tgz" @@ -251,25 +251,48 @@ js-tokens "^4.0.0" picocolors "^1.1.1" +"@babel/code-frame@^7.28.6", "@babel/code-frame@^7.29.0": + version "7.29.0" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.29.0.tgz#7cd7a59f15b3cc0dcd803038f7792712a7d0b15c" + integrity sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw== + dependencies: + "@babel/helper-validator-identifier" "^7.28.5" + js-tokens "^4.0.0" + picocolors "^1.1.1" + +"@babel/code-frame@^7.29.7": + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.29.7.tgz#f2fbbfea87c44a21590ec515b778b2c26d8866e7" + integrity sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw== + dependencies: + "@babel/helper-validator-identifier" "^7.29.7" + js-tokens "^4.0.0" + picocolors "^1.1.1" + "@babel/compat-data@^7.27.2", "@babel/compat-data@^7.27.7", "@babel/compat-data@^7.28.0": version "7.28.4" resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.4.tgz" integrity sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw== -"@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.0.0-0 || ^8.0.0-0 <8.0.0", "@babel/core@^7.12.0", "@babel/core@^7.13.0", "@babel/core@^7.21.3", "@babel/core@^7.25.9", "@babel/core@^7.4.0 || ^8.0.0-0 <8.0.0": - version "7.28.4" - resolved "https://registry.npmjs.org/@babel/core/-/core-7.28.4.tgz" - integrity sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA== - dependencies: - "@babel/code-frame" "^7.27.1" - "@babel/generator" "^7.28.3" - "@babel/helper-compilation-targets" "^7.27.2" - "@babel/helper-module-transforms" "^7.28.3" - "@babel/helpers" "^7.28.4" - "@babel/parser" "^7.28.4" - "@babel/template" "^7.27.2" - "@babel/traverse" "^7.28.4" - "@babel/types" "^7.28.4" +"@babel/compat-data@^7.29.7": + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.29.7.tgz#6f0237f0f36d2e51c0570a636faed9d2d0efe629" + integrity sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg== + +"@babel/core@^7.21.3", "@babel/core@^7.25.9": + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.29.7.tgz#80c10b17248082968b57a857b91640971f2070f7" + integrity sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA== + dependencies: + "@babel/code-frame" "^7.29.7" + "@babel/generator" "^7.29.7" + "@babel/helper-compilation-targets" "^7.29.7" + "@babel/helper-module-transforms" "^7.29.7" + "@babel/helpers" "^7.29.7" + "@babel/parser" "^7.29.7" + "@babel/template" "^7.29.7" + "@babel/traverse" "^7.29.7" + "@babel/types" "^7.29.7" "@jridgewell/remapping" "^2.3.5" convert-source-map "^2.0.0" debug "^4.1.0" @@ -288,6 +311,28 @@ "@jridgewell/trace-mapping" "^0.3.28" jsesc "^3.0.2" +"@babel/generator@^7.29.0": + version "7.29.1" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.29.1.tgz#d09876290111abbb00ef962a7b83a5307fba0d50" + integrity sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw== + dependencies: + "@babel/parser" "^7.29.0" + "@babel/types" "^7.29.0" + "@jridgewell/gen-mapping" "^0.3.12" + "@jridgewell/trace-mapping" "^0.3.28" + jsesc "^3.0.2" + +"@babel/generator@^7.29.7": + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.29.7.tgz#cca0b8827e6bcf3ba176788e7f3b180ad6db2fa3" + integrity sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ== + dependencies: + "@babel/parser" "^7.29.7" + "@babel/types" "^7.29.7" + "@jridgewell/gen-mapping" "^0.3.12" + "@jridgewell/trace-mapping" "^0.3.28" + jsesc "^3.0.2" + "@babel/helper-annotate-as-pure@^7.27.1", "@babel/helper-annotate-as-pure@^7.27.3": version "7.27.3" resolved "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz" @@ -306,6 +351,17 @@ lru-cache "^5.1.1" semver "^6.3.1" +"@babel/helper-compilation-targets@^7.29.7": + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz#7a1def704302401c47f64fa85589e974ae217042" + integrity sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g== + dependencies: + "@babel/compat-data" "^7.29.7" + "@babel/helper-validator-option" "^7.29.7" + browserslist "^4.24.0" + lru-cache "^5.1.1" + semver "^6.3.1" + "@babel/helper-create-class-features-plugin@^7.27.1", "@babel/helper-create-class-features-plugin@^7.28.3": version "7.28.3" resolved "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.3.tgz" @@ -344,6 +400,11 @@ resolved "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz" integrity sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw== +"@babel/helper-globals@^7.29.7": + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/helper-globals/-/helper-globals-7.29.7.tgz#f04a96fbd8473241b1079243f5b3f03a3010ab7b" + integrity sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA== + "@babel/helper-member-expression-to-functions@^7.27.1": version "7.27.1" resolved "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.27.1.tgz" @@ -360,7 +421,23 @@ "@babel/traverse" "^7.27.1" "@babel/types" "^7.27.1" -"@babel/helper-module-transforms@^7.27.1", "@babel/helper-module-transforms@^7.28.3": +"@babel/helper-module-imports@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz#60632cbd6ffb70b22823187201116762a03e2d5c" + integrity sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw== + dependencies: + "@babel/traverse" "^7.28.6" + "@babel/types" "^7.28.6" + +"@babel/helper-module-imports@^7.29.7": + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz#ef25048a518e828d7393fac5882ddd73921d7396" + integrity sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g== + dependencies: + "@babel/traverse" "^7.29.7" + "@babel/types" "^7.29.7" + +"@babel/helper-module-transforms@^7.27.1": version "7.28.3" resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz" integrity sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw== @@ -369,6 +446,24 @@ "@babel/helper-validator-identifier" "^7.27.1" "@babel/traverse" "^7.28.3" +"@babel/helper-module-transforms@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz#9312d9d9e56edc35aeb6e95c25d4106b50b9eb1e" + integrity sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA== + dependencies: + "@babel/helper-module-imports" "^7.28.6" + "@babel/helper-validator-identifier" "^7.28.5" + "@babel/traverse" "^7.28.6" + +"@babel/helper-module-transforms@^7.29.7": + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz#b062747a5997ba138637201328bbff77960574ae" + integrity sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg== + dependencies: + "@babel/helper-module-imports" "^7.29.7" + "@babel/helper-validator-identifier" "^7.29.7" + "@babel/traverse" "^7.29.7" + "@babel/helper-optimise-call-expression@^7.27.1": version "7.27.1" resolved "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz" @@ -381,6 +476,11 @@ resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz" integrity sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw== +"@babel/helper-plugin-utils@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz#6f13ea251b68c8532e985fd532f28741a8af9ac8" + integrity sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug== + "@babel/helper-remap-async-to-generator@^7.27.1": version "7.27.1" resolved "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz" @@ -412,16 +512,36 @@ resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz" integrity sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA== +"@babel/helper-string-parser@^7.29.7": + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz#7f0871d99824d23137d60f86fcf6130fd5a1b51f" + integrity sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw== + "@babel/helper-validator-identifier@^7.27.1": version "7.27.1" resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz" integrity sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow== +"@babel/helper-validator-identifier@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz#010b6938fab7cb7df74aa2bbc06aa503b8fe5fb4" + integrity sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q== + +"@babel/helper-validator-identifier@^7.29.7": + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz#bd87084ced0c796ec46bda492de6e83d29e89fc2" + integrity sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg== + "@babel/helper-validator-option@^7.27.1": version "7.27.1" resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz" integrity sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg== +"@babel/helper-validator-option@^7.29.7": + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz#cf315be940213b354eb4abcc0bd01ebe3f73bc2a" + integrity sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw== + "@babel/helper-wrap-function@^7.27.1": version "7.28.3" resolved "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.3.tgz" @@ -431,13 +551,13 @@ "@babel/traverse" "^7.28.3" "@babel/types" "^7.28.2" -"@babel/helpers@^7.28.4": - version "7.28.4" - resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz" - integrity sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w== +"@babel/helpers@^7.29.7": + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.29.7.tgz#45abfde7548997e34376c3e69feb475cffb4a607" + integrity sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg== dependencies: - "@babel/template" "^7.27.2" - "@babel/types" "^7.28.4" + "@babel/template" "^7.29.7" + "@babel/types" "^7.29.7" "@babel/parser@^7.27.2", "@babel/parser@^7.28.3", "@babel/parser@^7.28.4": version "7.28.4" @@ -446,6 +566,20 @@ dependencies: "@babel/types" "^7.28.4" +"@babel/parser@^7.28.6", "@babel/parser@^7.29.0": + version "7.29.3" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.29.3.tgz#116f70a77958307fceac27747573032f8a62f88e" + integrity sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA== + dependencies: + "@babel/types" "^7.29.0" + +"@babel/parser@^7.29.7": + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.29.7.tgz#837b87387cbf5ec5530cb634b3c622f68edb9334" + integrity sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg== + dependencies: + "@babel/types" "^7.29.7" + "@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.27.1": version "7.27.1" resolved "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.27.1.tgz" @@ -730,14 +864,14 @@ "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-transform-modules-systemjs@^7.27.1": - version "7.27.1" - resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.27.1.tgz" - integrity sha512-w5N1XzsRbc0PQStASMksmUeqECuzKuTJer7kFagK8AXgpCMkeDMO5S+aaFb7A51ZYDF7XI34qsTX+fkHiIm5yA== + version "7.29.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.4.tgz#f621105da99919c15cf4bde6fcc7346ef95e7b20" + integrity sha512-N7QmZ0xRZfjHOfZeQLJjwgX2zS9pdGHSVl/cjSGlo4dXMqvurfxXDMKY4RqEKzPozV78VMcd0lxyG13mlbKc4w== dependencies: - "@babel/helper-module-transforms" "^7.27.1" - "@babel/helper-plugin-utils" "^7.27.1" - "@babel/helper-validator-identifier" "^7.27.1" - "@babel/traverse" "^7.27.1" + "@babel/helper-module-transforms" "^7.28.6" + "@babel/helper-plugin-utils" "^7.28.6" + "@babel/helper-validator-identifier" "^7.28.5" + "@babel/traverse" "^7.29.0" "@babel/plugin-transform-modules-umd@^7.27.1": version "7.27.1" @@ -1124,6 +1258,24 @@ "@babel/parser" "^7.27.2" "@babel/types" "^7.27.1" +"@babel/template@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.28.6.tgz#0e7e56ecedb78aeef66ce7972b082fce76a23e57" + integrity sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ== + dependencies: + "@babel/code-frame" "^7.28.6" + "@babel/parser" "^7.28.6" + "@babel/types" "^7.28.6" + +"@babel/template@^7.29.7": + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.29.7.tgz#4d9d4004f645cdd304de958c725162784ecac700" + integrity sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg== + dependencies: + "@babel/code-frame" "^7.29.7" + "@babel/parser" "^7.29.7" + "@babel/types" "^7.29.7" + "@babel/traverse@^7.25.9", "@babel/traverse@^7.27.1", "@babel/traverse@^7.28.0", "@babel/traverse@^7.28.3", "@babel/traverse@^7.28.4": version "7.28.4" resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.4.tgz" @@ -1137,6 +1289,32 @@ "@babel/types" "^7.28.4" debug "^4.3.1" +"@babel/traverse@^7.28.6", "@babel/traverse@^7.29.0": + version "7.29.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.29.0.tgz#f323d05001440253eead3c9c858adbe00b90310a" + integrity sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA== + dependencies: + "@babel/code-frame" "^7.29.0" + "@babel/generator" "^7.29.0" + "@babel/helper-globals" "^7.28.0" + "@babel/parser" "^7.29.0" + "@babel/template" "^7.28.6" + "@babel/types" "^7.29.0" + debug "^4.3.1" + +"@babel/traverse@^7.29.7": + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.29.7.tgz#c47b07a41b95da0907d026b5dd894d98de7d2f2d" + integrity sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw== + dependencies: + "@babel/code-frame" "^7.29.7" + "@babel/generator" "^7.29.7" + "@babel/helper-globals" "^7.29.7" + "@babel/parser" "^7.29.7" + "@babel/template" "^7.29.7" + "@babel/types" "^7.29.7" + debug "^4.3.1" + "@babel/types@^7.21.3", "@babel/types@^7.27.1", "@babel/types@^7.27.3", "@babel/types@^7.28.2", "@babel/types@^7.28.4", "@babel/types@^7.4.4": version "7.28.4" resolved "https://registry.npmjs.org/@babel/types/-/types-7.28.4.tgz" @@ -1145,6 +1323,22 @@ "@babel/helper-string-parser" "^7.27.1" "@babel/helper-validator-identifier" "^7.27.1" +"@babel/types@^7.28.6", "@babel/types@^7.29.0": + version "7.29.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.29.0.tgz#9f5b1e838c446e72cf3cd4b918152b8c605e37c7" + integrity sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A== + dependencies: + "@babel/helper-string-parser" "^7.27.1" + "@babel/helper-validator-identifier" "^7.28.5" + +"@babel/types@^7.29.7": + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.29.7.tgz#8005e31d82712ee7adaef6e23c63b71a62770a92" + integrity sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA== + dependencies: + "@babel/helper-string-parser" "^7.29.7" + "@babel/helper-validator-identifier" "^7.29.7" + "@braintree/sanitize-url@^7.1.1": version "7.1.1" resolved "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-7.1.1.tgz" @@ -1627,7 +1821,7 @@ webpack "^5.95.0" webpackbar "^6.0.1" -"@docusaurus/core@^2.0.0-alpha.60 || ^2.0.0 || ^3.0.0", "@docusaurus/core@^3.9.2", "@docusaurus/core@3.9.2": +"@docusaurus/core@3.9.2", "@docusaurus/core@^3.9.2": version "3.9.2" resolved "https://registry.npmjs.org/@docusaurus/core/-/core-3.9.2.tgz" integrity sha512-HbjwKeC+pHUFBfLMNzuSjqFE/58+rLVKmOU3lxQrpsxLBOGosYco/Q0GduBb0/jEMRiyEqjNT/01rRdOMWq5pw== @@ -1723,7 +1917,7 @@ vfile "^6.0.1" webpack "^5.88.1" -"@docusaurus/module-type-aliases@^3.9.2", "@docusaurus/module-type-aliases@3.9.2": +"@docusaurus/module-type-aliases@3.9.2", "@docusaurus/module-type-aliases@^3.9.2": version "3.9.2" resolved "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.9.2.tgz" integrity sha512-8qVe2QA9hVLzvnxP46ysuofJUIc/yYQ82tvA/rBTrnpXtCjNSFLxEZfd5U8cYZuJIVlkPxamsIgwd5tGZXfvew== @@ -1760,7 +1954,7 @@ utility-types "^3.10.0" webpack "^5.88.1" -"@docusaurus/plugin-content-docs@*", "@docusaurus/plugin-content-docs@3.9.2": +"@docusaurus/plugin-content-docs@3.9.2": version "3.9.2" resolved "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.9.2.tgz" integrity sha512-C5wZsGuKTY8jEYsqdxhhFOe1ZDjH0uIYJ9T/jebHwkyxqnr4wW0jTkB72OMqNjsoQRcb0JN3PcSeTwFlVgzCZg== @@ -1821,7 +2015,7 @@ react-json-view-lite "^2.3.0" tslib "^2.6.0" -"@docusaurus/plugin-google-analytics@^3.9.2", "@docusaurus/plugin-google-analytics@3.9.2": +"@docusaurus/plugin-google-analytics@3.9.2", "@docusaurus/plugin-google-analytics@^3.9.2": version "3.9.2" resolved "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.9.2.tgz" integrity sha512-mAwwQJ1Us9jL/lVjXtErXto4p4/iaLlweC54yDUK1a97WfkC6Z2k5/769JsFgwOwOP+n5mUQGACXOEQ0XDuVUw== @@ -1852,7 +2046,7 @@ "@docusaurus/utils-validation" "3.9.2" tslib "^2.6.0" -"@docusaurus/plugin-sitemap@^3.9.2", "@docusaurus/plugin-sitemap@3.9.2": +"@docusaurus/plugin-sitemap@3.9.2", "@docusaurus/plugin-sitemap@^3.9.2": version "3.9.2" resolved "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.9.2.tgz" integrity sha512-WLh7ymgDXjG8oPoM/T4/zUP7KcSuFYRZAUTl8vR6VzYkfc18GBM4xLhcT+AKOwun6kBivYKUJf+vlqYJkm+RHw== @@ -1994,7 +2188,7 @@ fs-extra "^11.1.1" tslib "^2.6.0" -"@docusaurus/types@^3.9.2", "@docusaurus/types@3.9.2": +"@docusaurus/types@3.9.2", "@docusaurus/types@^3.9.2": version "3.9.2" resolved "https://registry.npmjs.org/@docusaurus/types/-/types-3.9.2.tgz" integrity sha512-Ux1JUNswg+EfUEmajJjyhIohKceitY/yzjRUpu04WXgvVz+fbhVC0p+R0JhvEu4ytw8zIAys2hrdpQPBHRIa8Q== @@ -2246,6 +2440,11 @@ dependencies: langium "3.3.1" +"@noble/hashes@1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.4.0.tgz#45814aa329f30e4fe0ba49426f49dfccdd066426" + integrity sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg== + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" @@ -2254,7 +2453,7 @@ "@nodelib/fs.stat" "2.0.5" run-parallel "^1.1.9" -"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": version "2.0.5" resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== @@ -2272,6 +2471,136 @@ resolved "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz" integrity sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg== +"@peculiar/asn1-cms@^2.6.0", "@peculiar/asn1-cms@^2.8.0": + version "2.8.0" + resolved "https://registry.yarnpkg.com/@peculiar/asn1-cms/-/asn1-cms-2.8.0.tgz#b48a8389319228f929e9acd8cee8da6c858738de" + integrity sha512-NgekZOrSJFSBFLFoLfwePguAWAx7z1+f2TEsWFUMyiqqfntZ4+S/S5hzqME3q4pCA0iOsFKdwiQ35dwY24eVqA== + dependencies: + "@peculiar/asn1-schema" "^2.8.0" + "@peculiar/asn1-x509" "^2.8.0" + "@peculiar/asn1-x509-attr" "^2.8.0" + asn1js "^3.0.10" + tslib "^2.8.1" + +"@peculiar/asn1-csr@^2.6.0": + version "2.8.0" + resolved "https://registry.yarnpkg.com/@peculiar/asn1-csr/-/asn1-csr-2.8.0.tgz#c9bb5dec2eaff824a705e82a4a58d45e6d2c35d0" + integrity sha512-akbF8+uvleHs8sejNPQxwmVFuInAg6FMNHOwMILXfP518YfFJwdR3jr6oNUPOaEJfuEhn/vkNOCIT6ASUd4mbg== + dependencies: + "@peculiar/asn1-schema" "^2.8.0" + "@peculiar/asn1-x509" "^2.8.0" + asn1js "^3.0.10" + tslib "^2.8.1" + +"@peculiar/asn1-ecc@^2.6.0": + version "2.8.0" + resolved "https://registry.yarnpkg.com/@peculiar/asn1-ecc/-/asn1-ecc-2.8.0.tgz#d51ab2b07eca98e0cf492d051e98bbd0a071305a" + integrity sha512-ohwlk+u9Rv2NOAY1c6MfHj45ATVF8R1DUN/WCgABiRtLi2ZftlZWZX7KvpAbU8v9xPcmoILfELeEABj/rn18AQ== + dependencies: + "@peculiar/asn1-schema" "^2.8.0" + "@peculiar/asn1-x509" "^2.8.0" + asn1js "^3.0.10" + tslib "^2.8.1" + +"@peculiar/asn1-pfx@^2.8.0": + version "2.8.0" + resolved "https://registry.yarnpkg.com/@peculiar/asn1-pfx/-/asn1-pfx-2.8.0.tgz#8e189b6455e2bf9e5f921bb150ea86d7e7d1875d" + integrity sha512-5yof1ytoB++RQtaFbqSUJ8pxDJtZT6vbVqZ8XoJ61ph7UjNVvfFwAilnCodqkNsAodpy13gDhoxZXw00pghnyg== + dependencies: + "@peculiar/asn1-cms" "^2.8.0" + "@peculiar/asn1-pkcs8" "^2.8.0" + "@peculiar/asn1-rsa" "^2.8.0" + "@peculiar/asn1-schema" "^2.8.0" + asn1js "^3.0.10" + tslib "^2.8.1" + +"@peculiar/asn1-pkcs8@^2.8.0": + version "2.8.0" + resolved "https://registry.yarnpkg.com/@peculiar/asn1-pkcs8/-/asn1-pkcs8-2.8.0.tgz#a46cf8857b9b063896afa41d2b8b2aa6a07a70a2" + integrity sha512-qAKXtLpBEw9LqhKpjw3ajZSXlBur+ipW+y2ivVBQAG6F6qRx94yO+1ZR4mvw+YaCfKSaOzLeYEzsPaBp4SJELA== + dependencies: + "@peculiar/asn1-schema" "^2.8.0" + "@peculiar/asn1-x509" "^2.8.0" + asn1js "^3.0.10" + tslib "^2.8.1" + +"@peculiar/asn1-pkcs9@^2.6.0": + version "2.8.0" + resolved "https://registry.yarnpkg.com/@peculiar/asn1-pkcs9/-/asn1-pkcs9-2.8.0.tgz#6d62697af0bbd4f30fdf0d23b4018f3f09620de3" + integrity sha512-b5nDWCnkV60+cQ141D6sVVwK9nz64R5n3zSVnklGd+ECdkW2Ol3U1a6yYFlalpSOaD557yuJB64A+q42jG7lUQ== + dependencies: + "@peculiar/asn1-cms" "^2.8.0" + "@peculiar/asn1-pfx" "^2.8.0" + "@peculiar/asn1-pkcs8" "^2.8.0" + "@peculiar/asn1-schema" "^2.8.0" + "@peculiar/asn1-x509" "^2.8.0" + "@peculiar/asn1-x509-attr" "^2.8.0" + asn1js "^3.0.10" + tslib "^2.8.1" + +"@peculiar/asn1-rsa@^2.6.0", "@peculiar/asn1-rsa@^2.8.0": + version "2.8.0" + resolved "https://registry.yarnpkg.com/@peculiar/asn1-rsa/-/asn1-rsa-2.8.0.tgz#9d98d0fc42fec50119d2881b8a9925d36daaea73" + integrity sha512-zHEUlCqB2mk7x2lxDwHHJy7hWZOPdGHVlsmITWKB5/PbQo61atbu9PJ/0r9dQNMwFzbKPXZ8uK8/91eUhRznSg== + dependencies: + "@peculiar/asn1-schema" "^2.8.0" + "@peculiar/asn1-x509" "^2.8.0" + asn1js "^3.0.10" + tslib "^2.8.1" + +"@peculiar/asn1-schema@^2.6.0", "@peculiar/asn1-schema@^2.8.0": + version "2.8.0" + resolved "https://registry.yarnpkg.com/@peculiar/asn1-schema/-/asn1-schema-2.8.0.tgz#69699f84259b2161607cabfc34e512a4023dbef9" + integrity sha512-7YT0U/ze0tF2QOBbE15gKZwy5tvgGyLRiRHLzhlbOpf7BT032oBSd0haZqXn5W6l26WLlu3dyxzjM+2638/z2Q== + dependencies: + "@peculiar/utils" "^2.0.2" + asn1js "^3.0.10" + tslib "^2.8.1" + +"@peculiar/asn1-x509-attr@^2.8.0": + version "2.8.0" + resolved "https://registry.yarnpkg.com/@peculiar/asn1-x509-attr/-/asn1-x509-attr-2.8.0.tgz#bd168e3f5e8bc23e56b1a97891f9f2fb7f730204" + integrity sha512-tHjkfS/qhMnmrlB2J9NhflQlQ7In3khO3CfmVrriOlpTeErY9ZIKOso1hQ5JQiyrJ7ShvqVPk7E5fQmbclkSKA== + dependencies: + "@peculiar/asn1-schema" "^2.8.0" + "@peculiar/asn1-x509" "^2.8.0" + asn1js "^3.0.10" + tslib "^2.8.1" + +"@peculiar/asn1-x509@^2.6.0", "@peculiar/asn1-x509@^2.8.0": + version "2.8.0" + resolved "https://registry.yarnpkg.com/@peculiar/asn1-x509/-/asn1-x509-2.8.0.tgz#9958a9ef35dec8426aabad78ffe8798e318b06e2" + integrity sha512-N0CMuhWUzsWEVq6F1q9X6+VKUnWzSW+cSVg+aPaGGwDdbFoFWTYgin5MHwXgpWd6y9COMBxnfy/Qc+Xc7F0Zwg== + dependencies: + "@peculiar/asn1-schema" "^2.8.0" + "@peculiar/utils" "^2.0.2" + asn1js "^3.0.10" + tslib "^2.8.1" + +"@peculiar/utils@^2.0.2": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@peculiar/utils/-/utils-2.0.3.tgz#a27ca4c4b73652e110f19a7d16d664f458a5528e" + integrity sha512-+oL3HPFRIZ1St2K50lWCXiioIgSoxzz7R1J3uF6neO2yl1sgmpgY6XXJH4BdpoDkMWznQTeYF6oWNDZLCdQ4eQ== + dependencies: + tslib "^2.8.1" + +"@peculiar/x509@^1.14.2": + version "1.14.3" + resolved "https://registry.yarnpkg.com/@peculiar/x509/-/x509-1.14.3.tgz#2c44c2b89474346afec38a0c2803ec4fb8ce959e" + integrity sha512-C2Xj8FZ0uHWeCXXqX5B4/gVFQmtSkiuOolzAgutjTfseNOHT3pUjljDZsTSxXFGgio54bCzVFqmEOUrIVk8RDA== + dependencies: + "@peculiar/asn1-cms" "^2.6.0" + "@peculiar/asn1-csr" "^2.6.0" + "@peculiar/asn1-ecc" "^2.6.0" + "@peculiar/asn1-pkcs9" "^2.6.0" + "@peculiar/asn1-rsa" "^2.6.0" + "@peculiar/asn1-schema" "^2.6.0" + "@peculiar/asn1-x509" "^2.6.0" + pvtsutils "^1.3.6" + reflect-metadata "^0.2.2" + tslib "^2.8.1" + tsyringe "^4.10.0" + "@pnpm/config.env-replace@^1.1.0": version "1.1.0" resolved "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz" @@ -2398,7 +2727,7 @@ "@svgr/babel-plugin-transform-react-native-svg" "8.1.0" "@svgr/babel-plugin-transform-svg-component" "8.0.0" -"@svgr/core@*", "@svgr/core@8.1.0": +"@svgr/core@8.1.0": version "8.1.0" resolved "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz" integrity sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA== @@ -2457,11 +2786,6 @@ dependencies: defer-to-connect "^2.0.1" -"@trysound/sax@0.2.0": - version "0.2.0" - resolved "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz" - integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== - "@types/body-parser@*": version "1.19.6" resolved "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz" @@ -2747,7 +3071,7 @@ "@types/range-parser" "*" "@types/send" "*" -"@types/express@*", "@types/express@^4.17.13", "@types/express@^4.17.21": +"@types/express@*": version "4.17.23" resolved "https://registry.npmjs.org/@types/express/-/express-4.17.23.tgz" integrity sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ== @@ -2757,6 +3081,16 @@ "@types/qs" "*" "@types/serve-static" "*" +"@types/express@^4.17.25": + version "4.17.25" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.25.tgz#070c8c73a6fee6936d65c195dbbfb7da5026649b" + integrity sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.33" + "@types/qs" "*" + "@types/serve-static" "^1" + "@types/geojson@*": version "7946.0.16" resolved "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz" @@ -2854,13 +3188,6 @@ resolved "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz" integrity sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA== -"@types/node-forge@^1.3.0": - version "1.3.14" - resolved "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.14.tgz" - integrity sha512-mhVF2BnD4BO+jtOp7z1CdzaK4mbuK0LLQYAvdOLqHTavxFNq4zA1EmYkpnFjP8HOUzedfQkRnp0E2ulSAYSzAw== - dependencies: - "@types/node" "*" - "@types/node@*": version "22.10.5" resolved "https://registry.npmjs.org/@types/node/-/node-22.10.5.tgz" @@ -2924,7 +3251,7 @@ "@types/history" "^4.7.11" "@types/react" "*" -"@types/react@*", "@types/react@^18.0.0", "@types/react@>= 16.8.0 < 20.0.0", "@types/react@>=16": +"@types/react@*", "@types/react@^18.0.0": version "18.3.18" resolved "https://registry.npmjs.org/@types/react/-/react-18.3.18.tgz" integrity sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ== @@ -2975,6 +3302,15 @@ "@types/node" "*" "@types/send" "<1" +"@types/serve-static@^1": + version "1.15.10" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.10.tgz#768169145a778f8f5dfcb6360aead414a3994fee" + integrity sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw== + dependencies: + "@types/http-errors" "*" + "@types/node" "*" + "@types/send" "<1" + "@types/sockjs@^0.3.36": version "0.3.36" resolved "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz" @@ -2992,12 +3328,7 @@ resolved "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz" integrity sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q== -"@types/unist@^2": - version "2.0.11" - resolved "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz" - integrity sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA== - -"@types/unist@^2.0.0", "@types/unist@^2.0.2": +"@types/unist@^2", "@types/unist@^2.0.0", "@types/unist@^2.0.2": version "2.0.11" resolved "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz" integrity sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA== @@ -3031,7 +3362,7 @@ resolved "https://registry.npmjs.org/@vercel/oidc/-/oidc-3.0.3.tgz" integrity sha512-yNEQvPcVrK9sIe637+I0jD6leluPxzwJKx/Haw6F4H77CdDsszUn5V3o96LPziXkSNE2B83+Z3mjqGKBK/R6Gg== -"@webassemblyjs/ast@^1.14.1", "@webassemblyjs/ast@1.14.1": +"@webassemblyjs/ast@1.14.1", "@webassemblyjs/ast@^1.14.1": version "1.14.1" resolved "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz" integrity sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ== @@ -3132,7 +3463,7 @@ "@webassemblyjs/wasm-gen" "1.14.1" "@webassemblyjs/wasm-parser" "1.14.1" -"@webassemblyjs/wasm-parser@^1.14.1", "@webassemblyjs/wasm-parser@1.14.1": +"@webassemblyjs/wasm-parser@1.14.1", "@webassemblyjs/wasm-parser@^1.14.1": version "1.14.1" resolved "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz" integrity sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ== @@ -3187,7 +3518,7 @@ acorn-walk@^8.0.0: dependencies: acorn "^8.11.0" -"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.0.0, acorn@^8.0.4, acorn@^8.11.0, acorn@^8.14.0, acorn@^8.15.0, acorn@^8.8.2: +acorn@^8.0.0, acorn@^8.0.4, acorn@^8.11.0, acorn@^8.14.0, acorn@^8.15.0, acorn@^8.8.2: version "8.15.0" resolved "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz" integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg== @@ -3205,7 +3536,7 @@ aggregate-error@^3.0.0: clean-stack "^2.0.0" indent-string "^4.0.0" -ai@^5.0.30, ai@5.0.76: +ai@5.0.76, ai@^5.0.30: version "5.0.76" resolved "https://registry.npmjs.org/ai/-/ai-5.0.76.tgz" integrity sha512-ZCxi1vrpyCUnDbtYrO/W8GLvyacV9689f00yshTIQ3mFFphbD7eIv40a2AOZBv3GGRA7SSRYIDnr56wcS/gyQg== @@ -3234,7 +3565,7 @@ ajv-keywords@^5.1.0: dependencies: fast-deep-equal "^3.1.3" -ajv@^6.12.5, ajv@^6.9.1: +ajv@^6.12.5: version "6.12.6" resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -3244,7 +3575,7 @@ ajv@^6.12.5, ajv@^6.9.1: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^8.0.0, ajv@^8.8.2, ajv@^8.9.0: +ajv@^8.0.0, ajv@^8.9.0: version "8.17.1" resolved "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz" integrity sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g== @@ -3261,7 +3592,7 @@ algoliasearch-helper@^3.26.0: dependencies: "@algolia/events" "^4.0.1" -algoliasearch@^5.28.0, algoliasearch@^5.37.0, "algoliasearch@>= 3.1 < 6", "algoliasearch@>= 4.9.1 < 6": +algoliasearch@^5.28.0, algoliasearch@^5.37.0: version "5.40.1" resolved "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.40.1.tgz" integrity sha512-iUNxcXUNg9085TJx0HJLjqtDE0r1RZ0GOGrt8KNQqQT5ugu8lZsHuMUYW/e0lHhq6xBvmktU9Bw4CXP9VQeKrg== @@ -3362,6 +3693,15 @@ array-union@^2.1.0: resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== +asn1js@^3.0.10, asn1js@^3.0.6: + version "3.0.10" + resolved "https://registry.yarnpkg.com/asn1js/-/asn1js-3.0.10.tgz#df26c874c8a8b41ca605efea47b2ad07551013dd" + integrity sha512-S2s3aOytiKdFRdulw2qPE51MzjzVOisppcVv7jVFR+Kw0kxwvFrDcYA0h7Ndqbmj0HkMIXYWaoj7fli8kgx1eg== + dependencies: + pvtsutils "^1.3.6" + pvutils "^1.1.5" + tslib "^2.8.1" + astring@^1.8.0: version "1.9.0" resolved "https://registry.npmjs.org/astring/-/astring-1.9.0.tgz" @@ -3465,23 +3805,23 @@ binary-extensions@^2.0.0: resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz" integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== -body-parser@1.20.3: - version "1.20.3" - resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz" - integrity sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g== +body-parser@~1.20.5: + version "1.20.6" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.6.tgz#60c789c78e0992d906da0a29d71ae01d15c1ed76" + integrity sha512-p5tAzS57i5MV9fZFDj9LeIiTZEufbSe2eDozP+ElheSUq1m74CRq1jI4mYNDdVs9vQztXFLuk/Gd6BWTdwRJ5g== dependencies: - bytes "3.1.2" + bytes "~3.1.2" content-type "~1.0.5" debug "2.6.9" depd "2.0.0" - destroy "1.2.0" - http-errors "2.0.0" - iconv-lite "0.4.24" - on-finished "2.4.1" - qs "6.13.0" - raw-body "2.5.2" + destroy "~1.2.0" + http-errors "~2.0.1" + iconv-lite "~0.4.24" + on-finished "~2.4.1" + qs "~6.15.1" + raw-body "~2.5.3" type-is "~1.6.18" - unpipe "1.0.0" + unpipe "~1.0.0" bonjour-service@^1.2.1: version "1.3.0" @@ -3525,13 +3865,20 @@ boxen@^7.0.0: wrap-ansi "^8.1.0" brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + version "1.1.16" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.16.tgz#723d3a30c0558c225abc9fc479a73e14e26c3c2f" + integrity sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw== dependencies: balanced-match "^1.0.0" concat-map "0.0.1" +brace-expansion@^2.0.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.1.2.tgz#0bba2271feb7d458b0d31ad13625aaa4754431e2" + integrity sha512-w5JZcKgdhDOgOwm8H+KgbosopHMuGcl6qbulwjtz3SM7I7P3yW1eAjzMPLrIE+NQ9vjgANKHWeMHnrT0OXW1oA== + dependencies: + balanced-match "^1.0.0" + braces@^3.0.3, braces@~3.0.2: version "3.0.3" resolved "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz" @@ -3539,7 +3886,7 @@ braces@^3.0.3, braces@~3.0.2: dependencies: fill-range "^7.1.1" -browserslist@^4.0.0, browserslist@^4.23.0, browserslist@^4.24.0, browserslist@^4.24.4, browserslist@^4.26.0, browserslist@^4.26.3, "browserslist@>= 4.21.0": +browserslist@^4.0.0, browserslist@^4.23.0, browserslist@^4.24.0, browserslist@^4.24.4, browserslist@^4.26.0, browserslist@^4.26.3: version "4.26.3" resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.26.3.tgz" integrity sha512-lAUU+02RFBuCKQPj/P6NgjlbCnLBMp4UtgTx7vNHd3XSIJF87s9a5rA3aH2yw3GS9DqZAUbOtZdCCiZeVRqt0w== @@ -3567,11 +3914,16 @@ bytes@3.0.0: resolved "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz" integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw== -bytes@3.1.2: +bytes@3.1.2, bytes@~3.1.2: version "3.1.2" resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== +bytestreamjs@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/bytestreamjs/-/bytestreamjs-2.0.1.tgz#a32947c7ce389a6fa11a09a9a563d0a45889535e" + integrity sha512-U1Z/ob71V/bXfVABvNr/Kumf5VyeQRBEm6Txb0PQ6S7V5GpBM3w4Cbqz/xPDicR5tN0uvDifng8C+5qECeGwyQ== + cacheable-lookup@^7.0.0: version "7.0.0" resolved "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz" @@ -3729,7 +4081,7 @@ chevrotain-allstar@~0.3.0: dependencies: lodash-es "^4.17.21" -chevrotain@^11.0.0, chevrotain@~11.0.3: +chevrotain@~11.0.3: version "11.0.3" resolved "https://registry.npmjs.org/chevrotain/-/chevrotain-11.0.3.tgz" integrity sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw== @@ -3806,12 +4158,7 @@ clsx@^1.2.1: resolved "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz" integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg== -clsx@^2.0.0: - version "2.1.1" - resolved "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz" - integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA== - -clsx@^2.1.1: +clsx@^2.0.0, clsx@^2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz" integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA== @@ -3863,6 +4210,11 @@ comma-separated-tokens@^2.0.0: resolved "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz" integrity sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg== +commander@7, commander@^7.2.0: + version "7.2.0" + resolved "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz" + integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== + commander@^10.0.0: version "10.0.1" resolved "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz" @@ -3878,21 +4230,11 @@ commander@^5.1.0: resolved "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz" integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg== -commander@^7.2.0: - version "7.2.0" - resolved "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz" - integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== - commander@^8.3.0: version "8.3.0" resolved "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz" integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== -commander@7: - version "7.2.0" - resolved "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz" - integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== - common-path-prefix@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz" @@ -3905,9 +4247,9 @@ compressible@~2.0.18: dependencies: mime-db ">= 1.43.0 < 2" -compression@^1.7.4: +compression@^1.8.1: version "1.8.1" - resolved "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.8.1.tgz#4a45d909ac16509195a9a28bd91094889c180d79" integrity sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w== dependencies: bytes "3.1.2" @@ -3972,9 +4314,9 @@ content-disposition@0.5.2: resolved "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz" integrity sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA== -content-disposition@0.5.4: +content-disposition@~0.5.4: version "0.5.4" - resolved "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== dependencies: safe-buffer "5.2.1" @@ -3989,15 +4331,15 @@ convert-source-map@^2.0.0: resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz" integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== -cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz" - integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== +cookie-signature@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.7.tgz#ab5dd7ab757c54e60f37ef6550f481c426d10454" + integrity sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA== -cookie@0.7.1: - version "0.7.1" - resolved "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz" - integrity sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w== +cookie@~0.7.1: + version "0.7.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.2.tgz#556369c472a2ba910f2979891b526b3436237ed7" + integrity sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w== copy-webpack-plugin@^11.0.0: version "11.0.0" @@ -4263,18 +4605,11 @@ cytoscape-fcose@^2.2.0: dependencies: cose-base "^2.2.0" -cytoscape@^3.2.0, cytoscape@^3.29.3: +cytoscape@^3.29.3: version "3.33.1" resolved "https://registry.npmjs.org/cytoscape/-/cytoscape-3.33.1.tgz" integrity sha512-iJc4TwyANnOGR1OmWhsS9ayRS3s+XQ185FmuHObThD+5AeJCakAAbWv8KimMTt08xCCLNgneQwFp+JRJOr9qGQ== -d3-array@^3.2.0, "d3-array@2 - 3", "d3-array@2.10.0 - 3", "d3-array@2.5.0 - 3", d3-array@3: - version "3.2.4" - resolved "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz" - integrity sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg== - dependencies: - internmap "1 - 2" - "d3-array@1 - 2": version "2.12.1" resolved "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz" @@ -4282,6 +4617,13 @@ d3-array@^3.2.0, "d3-array@2 - 3", "d3-array@2.10.0 - 3", "d3-array@2.5.0 - 3", dependencies: internmap "^1.0.0" +"d3-array@2 - 3", "d3-array@2.10.0 - 3", "d3-array@2.5.0 - 3", d3-array@3, d3-array@^3.2.0: + version "3.2.4" + resolved "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz" + integrity sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg== + dependencies: + internmap "1 - 2" + d3-axis@3: version "3.0.0" resolved "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz" @@ -4391,16 +4733,16 @@ d3-hierarchy@3: dependencies: d3-color "1 - 3" -d3-path@^3.1.0, "d3-path@1 - 3", d3-path@3: - version "3.1.0" - resolved "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz" - integrity sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ== - d3-path@1: version "1.0.9" resolved "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz" integrity sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg== +"d3-path@1 - 3", d3-path@3, d3-path@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz" + integrity sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ== + d3-polygon@3: version "3.0.1" resolved "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz" @@ -4448,13 +4790,6 @@ d3-scale@4: resolved "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz" integrity sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ== -d3-shape@^1.2.0: - version "1.3.7" - resolved "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz" - integrity sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw== - dependencies: - d3-path "1" - d3-shape@3: version "3.2.0" resolved "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz" @@ -4462,6 +4797,13 @@ d3-shape@3: dependencies: d3-path "^3.1.0" +d3-shape@^1.2.0: + version "1.3.7" + resolved "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz" + integrity sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw== + dependencies: + d3-path "1" + "d3-time-format@2 - 4", d3-time-format@4: version "4.1.0" resolved "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz" @@ -4557,13 +4899,6 @@ debounce@^1.2.1: resolved "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz" integrity sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug== -debug@^4.0.0, debug@^4.1.0, debug@^4.3.1, debug@^4.4.1, debug@4: - version "4.4.3" - resolved "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz" - integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== - dependencies: - ms "^2.1.3" - debug@2.6.9: version "2.6.9" resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" @@ -4571,6 +4906,13 @@ debug@2.6.9: dependencies: ms "2.0.0" +debug@4, debug@^4.0.0, debug@^4.1.0, debug@^4.3.1, debug@^4.4.1: + version "4.4.3" + resolved "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz" + integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== + dependencies: + ms "^2.1.3" + decode-named-character-reference@^1.0.0: version "1.2.0" resolved "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.2.0.tgz" @@ -4648,22 +4990,22 @@ delaunator@5: dependencies: robust-predicates "^3.0.2" +depd@2.0.0, depd@~2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + depd@~1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz" integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== -depd@2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" - integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== - dequal@^2.0.0, dequal@^2.0.3: version "2.0.3" resolved "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz" integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== -destroy@1.2.0: +destroy@1.2.0, destroy@~1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz" integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== @@ -4772,9 +5114,9 @@ domhandler@^5.0.2, domhandler@^5.0.3: domelementtype "^2.3.0" dompurify@^3.2.5: - version "3.3.0" - resolved "https://registry.npmjs.org/dompurify/-/dompurify-3.3.0.tgz" - integrity sha512-r+f6MYR1gGN1eJv0TVQbhA7if/U7P87cdPl3HN5rikqaBSBxLiCb/b9O+2eG0cxz0ghyU+mU1QkbsOwERMYlWQ== + version "3.4.12" + resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.4.12.tgz#6fa2265e9bbdce882c4ace4107626051b448ffa8" + integrity sha512-zQvGet8Z2sWbQhCmfFz/T5QWH2oBmjnqK3qvOjaqaNLrLEF912WamU+ohnTp0TCep/MFVHpdJuCZEdFOdTnEFg== optionalDependencies: "@types/trusted-types" "^2.0.7" @@ -4865,11 +5207,6 @@ emoticon@^4.0.1: resolved "https://registry.npmjs.org/emoticon/-/emoticon-4.1.0.tgz" integrity sha512-VWZfnxqwNcc51hIy/sbOdEem6D+cVtpPzEEtVAFdaas30+1dgkyaOQ4sQ6Bp0tOMqWO1v+HQfYaoodOkdhK6SQ== -encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz" - integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== - encodeurl@~2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz" @@ -5121,39 +5458,39 @@ execa@5.1.1: signal-exit "^3.0.3" strip-final-newline "^2.0.0" -express@^4.21.2: - version "4.21.2" - resolved "https://registry.npmjs.org/express/-/express-4.21.2.tgz" - integrity sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA== +express@^4.22.1: + version "4.22.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.22.2.tgz#c17ae0981e5efc24b22272f0e041c4662503b700" + integrity sha512-IuL+Elrou2ZvCFHs18/CIzy2Nzvo25nZ1/D2eIZlz7c+QUayAcYoiM2BthCjs+EBHVpjYjcuLDAiCWgeIX3X1Q== dependencies: accepts "~1.3.8" array-flatten "1.1.1" - body-parser "1.20.3" - content-disposition "0.5.4" + body-parser "~1.20.5" + content-disposition "~0.5.4" content-type "~1.0.4" - cookie "0.7.1" - cookie-signature "1.0.6" + cookie "~0.7.1" + cookie-signature "~1.0.6" debug "2.6.9" depd "2.0.0" encodeurl "~2.0.0" escape-html "~1.0.3" etag "~1.8.1" - finalhandler "1.3.1" - fresh "0.5.2" - http-errors "2.0.0" + finalhandler "~1.3.1" + fresh "~0.5.2" + http-errors "~2.0.0" merge-descriptors "1.0.3" methods "~1.1.2" - on-finished "2.4.1" + on-finished "~2.4.1" parseurl "~1.3.3" - path-to-regexp "0.1.12" + path-to-regexp "~0.1.12" proxy-addr "~2.0.7" - qs "6.13.0" + qs "~6.15.1" range-parser "~1.2.1" safe-buffer "5.2.1" - send "0.19.0" - serve-static "1.16.2" + send "~0.19.0" + serve-static "~1.16.2" setprototypeof "1.2.0" - statuses "2.0.1" + statuses "~2.0.1" type-is "~1.6.18" utils-merge "1.0.1" vary "~1.1.2" @@ -5197,9 +5534,9 @@ fast-json-stable-stringify@^2.0.0: integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== fast-uri@^3.0.1: - version "3.0.5" - resolved "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.5.tgz" - integrity sha512-5JnBCWpFlMo0a3ciDy/JckMzzv1U9coZrIhedq+HXxxUfDTAiS0LA8OKVao4G9BxmCVck/jtA5r3KAtRWEyD8Q== + version "3.1.4" + resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.1.4.tgz#3b3daf9ce68f41f956df0b505132c0cfce9ec7af" + integrity sha512-8JnbkQ4juDyvYs4mgFGQqg4yCYtFDtUtmp2QIQq11ZZe5CFQ5wcqm1rqDgAh/QdMySuBnPzMUiJUNZG5N/AiQw== fastq@^1.6.0: version "1.19.1" @@ -5236,7 +5573,7 @@ figures@^3.2.0: dependencies: escape-string-regexp "^1.0.5" -file-loader@*, file-loader@^6.2.0: +file-loader@^6.2.0: version "6.2.0" resolved "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz" integrity sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw== @@ -5251,17 +5588,17 @@ fill-range@^7.1.1: dependencies: to-regex-range "^5.0.1" -finalhandler@1.3.1: - version "1.3.1" - resolved "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz" - integrity sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ== +finalhandler@~1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.3.2.tgz#1ebc2228fc7673aac4a472c310cc05b77d852b88" + integrity sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg== dependencies: debug "2.6.9" encodeurl "~2.0.0" escape-html "~1.0.3" - on-finished "2.4.1" + on-finished "~2.4.1" parseurl "~1.3.3" - statuses "2.0.1" + statuses "~2.0.2" unpipe "~1.0.0" find-cache-dir@^4.0.0: @@ -5286,9 +5623,9 @@ flat@^5.0.2: integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== follow-redirects@^1.0.0: - version "1.15.11" - resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz" - integrity sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ== + version "1.16.0" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.16.0.tgz#28474a159d3b9d11ef62050a14ed60e4df6d61bc" + integrity sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw== form-data-encoder@^2.1.2: version "2.1.4" @@ -5310,9 +5647,9 @@ fraction.js@^4.3.7: resolved "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz" integrity sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew== -fresh@0.5.2: +fresh@~0.5.2: version "0.5.2" - resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== fs-extra@^11.1.1, fs-extra@^11.2.0: @@ -5324,6 +5661,16 @@ fs-extra@^11.1.1, fs-extra@^11.2.0: jsonfile "^6.0.1" universalify "^2.0.0" +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + function-bind@^1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz" @@ -5412,6 +5759,16 @@ glob-to-regexp@^0.4.1: resolved "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz" integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== +glob@^9.0.0, glob@^9.2.0: + version "9.3.5" + resolved "https://registry.yarnpkg.com/glob/-/glob-9.3.5.tgz#ca2ed8ca452781a3009685607fdf025a899dfe21" + integrity sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q== + dependencies: + fs.realpath "^1.0.0" + minimatch "^8.0.2" + minipass "^4.2.4" + path-scurry "^1.6.1" + global-dirs@^3.0.0: version "3.0.1" resolved "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz" @@ -5469,16 +5826,16 @@ got@^12.1.0: p-cancelable "^3.0.0" responselike "^3.0.0" -graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.11, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: - version "4.2.11" - resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz" - integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== - graceful-fs@4.2.10: version "4.2.10" resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz" integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.11, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: + version "4.2.11" + resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + gray-matter@^4.0.3: version "4.0.3" resolved "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz" @@ -5865,16 +6222,16 @@ http-errors@~1.6.2: setprototypeof "1.1.0" statuses ">= 1.4.0 < 2" -http-errors@2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz" - integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== +http-errors@~2.0.0, http-errors@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.1.tgz#36d2f65bc909c8790018dd36fb4d93da6caae06b" + integrity sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ== dependencies: - depd "2.0.0" - inherits "2.0.4" - setprototypeof "1.2.0" - statuses "2.0.1" - toidentifier "1.0.1" + depd "~2.0.0" + inherits "~2.0.4" + setprototypeof "~1.2.0" + statuses "~2.0.2" + toidentifier "~1.0.1" http-parser-js@>=0.5.1: version "0.5.10" @@ -5882,9 +6239,9 @@ http-parser-js@>=0.5.1: integrity sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA== http-proxy-middleware@^2.0.9: - version "2.0.9" - resolved "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.9.tgz" - integrity sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q== + version "2.0.10" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.10.tgz#b2df7b705203d7a8c269ac8450cf96b00c532f94" + integrity sha512-RKzRWNPxUZqbuk3BC5mGVJbBnWgr+diEnjJexIOytFbBzDy88Fbh/YvBr3DsNrl1jYAfjWfpATEv0NO35FDuPQ== dependencies: "@types/http-proxy" "^1.17.8" http-proxy "^1.18.1" @@ -5919,13 +6276,6 @@ hyperdyperid@^1.2.0: resolved "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz" integrity sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A== -iconv-lite@0.4.24: - version "0.4.24" - resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - iconv-lite@0.6: version "0.6.3" resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz" @@ -5933,6 +6283,13 @@ iconv-lite@0.6: dependencies: safer-buffer ">= 2.1.2 < 3.0.0" +iconv-lite@~0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + icss-utils@^5.0.0, icss-utils@^5.1.0: version "5.1.0" resolved "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz" @@ -5981,46 +6338,41 @@ infima@0.2.0-alpha.45: resolved "https://registry.npmjs.org/infima/-/infima-0.2.0-alpha.45.tgz" integrity sha512-uyH0zfr1erU1OohLk0fT4Rrb94AOhguWNOcD9uGrSpRvNB+6gZXUoJX5J0NtvzBO10YZ9PgvA4NFgt+fYg8ojw== -inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3, inherits@2.0.4: - version "2.0.4" - resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - inherits@2.0.3: version "2.0.3" resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== -ini@^1.3.4: - version "1.3.8" - resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz" - integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== - -ini@~1.3.0: - version "1.3.8" - resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz" - integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== +inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3, inherits@~2.0.4: + version "2.0.4" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== ini@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz" integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== +ini@^1.3.4, ini@~1.3.0: + version "1.3.8" + resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + inline-style-parser@0.2.4: version "0.2.4" resolved "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.4.tgz" integrity sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q== -internmap@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz" - integrity sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw== - "internmap@1 - 2": version "2.0.3" resolved "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz" integrity sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg== +internmap@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz" + integrity sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw== + invariant@^2.2.4: version "2.2.4" resolved "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz" @@ -6028,16 +6380,16 @@ invariant@^2.2.4: dependencies: loose-envify "^1.0.0" -ipaddr.js@^2.1.0: - version "2.2.0" - resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz" - integrity sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA== - ipaddr.js@1.9.1: version "1.9.1" resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== +ipaddr.js@^2.1.0: + version "2.2.0" + resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz" + integrity sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA== + is-alphabetical@^2.0.0: version "2.0.1" resolved "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz" @@ -6225,16 +6577,16 @@ is-yarn-global@^0.4.0: resolved "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.4.1.tgz" integrity sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ== -isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" - integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== - isarray@0.0.1: version "0.0.1" resolved "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + isexe@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" @@ -6281,10 +6633,10 @@ jiti@^1.20.0: resolved "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz" integrity sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A== -joi@^17.4.0, joi@^17.9.2: - version "17.13.3" - resolved "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz" - integrity sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA== +joi@^17.13.4, joi@^17.9.2: + version "17.13.4" + resolved "https://registry.yarnpkg.com/joi/-/joi-17.13.4.tgz#ad6153d97ce558eb3a3b593e0d43eab51df1c474" + integrity sha512-1RuuER6kmt8K8I3nIWvPZKi5RQCb568ZPyY4Pwjlua+yo+63ZTmIwxLZH0heBmiKN4uxjvCiarDrjaeH84xicQ== dependencies: "@hapi/hoek" "^9.3.0" "@hapi/topo" "^5.1.0" @@ -6408,13 +6760,13 @@ latest-version@^7.0.0: dependencies: package-json "^8.1.0" -launch-editor@^2.6.1: - version "2.11.1" - resolved "https://registry.npmjs.org/launch-editor/-/launch-editor-2.11.1.tgz" - integrity sha512-SEET7oNfgSaB6Ym0jufAdCeo3meJVeCaaDyzRygy0xsp2BFKCprcfHljTq4QkzTLUxEKkFK6OK4811YM2oSrRg== +launch-editor@^2.14.1: + version "2.14.1" + resolved "https://registry.yarnpkg.com/launch-editor/-/launch-editor-2.14.1.tgz#f7e0da3f58aaea03fea01074d840b5f739ed7ddc" + integrity sha512-QWBrQsMpH7gPr965dsKD/3cKWiNoTjpATQf++Xq63N6sKRGMwlVXz41O1IZTMfZQgBctD/K5Zt06+/I6pP6+HA== dependencies: picocolors "^1.1.1" - shell-quote "^1.8.3" + shell-quote "^1.8.4" layout-base@^1.0.0: version "1.0.2" @@ -6471,7 +6823,7 @@ locate-path@^7.1.0: dependencies: p-locate "^6.0.0" -lodash-es@^4.17.21, lodash-es@4.17.21: +lodash-es@4.17.21, lodash-es@^4.17.21: version "4.17.21" resolved "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz" integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw== @@ -6520,6 +6872,11 @@ lowercase-keys@^3.0.0: resolved "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz" integrity sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ== +lru-cache@^10.2.0: + version "10.4.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" + integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== + lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz" @@ -7279,60 +7636,41 @@ micromatch@^4.0.2, micromatch@^4.0.5, micromatch@^4.0.8: braces "^3.0.3" picomatch "^2.3.1" +mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": + version "1.52.0" + resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + mime-db@^1.54.0: version "1.54.0" resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz" integrity sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ== -"mime-db@>= 1.43.0 < 2": - version "1.52.0" - resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== - mime-db@~1.33.0: version "1.33.0" resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz" integrity sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ== -mime-db@1.52.0: - version "1.52.0" - resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== - -mime-types@^2.1.27: - version "2.1.35" - resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" - integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== - dependencies: - mime-db "1.52.0" - -mime-types@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz" - integrity sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA== - dependencies: - mime-db "^1.54.0" - -mime-types@~2.1.17, mime-types@2.1.18: +mime-types@2.1.18, mime-types@~2.1.17: version "2.1.18" resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz" integrity sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ== dependencies: mime-db "~1.33.0" -mime-types@~2.1.24: +mime-types@^2.1.27, mime-types@~2.1.24, mime-types@~2.1.34: version "2.1.35" resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== dependencies: mime-db "1.52.0" -mime-types@~2.1.34: - version "2.1.35" - resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" - integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== +mime-types@^3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz" + integrity sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA== dependencies: - mime-db "1.52.0" + mime-db "^1.54.0" mime@1.6.0: version "1.6.0" @@ -7367,18 +7705,35 @@ minimalistic-assert@^1.0.0: resolved "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== -minimatch@^3.1.2, minimatch@3.1.2: +minimatch@3.1.2, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== dependencies: brace-expansion "^1.1.7" +minimatch@^8.0.2: + version "8.0.7" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-8.0.7.tgz#954766e22da88a3e0a17ad93b58c15c9d8a579de" + integrity sha512-V+1uQNdzybxa14e/p00HZnQNNcTjnRJjDxg2V8wtkjFctq4M7hXFws4oekyTP0Jebeq7QYtpFyOeBAjc88zvYg== + dependencies: + brace-expansion "^2.0.1" + minimist@^1.2.0: version "1.2.8" resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== +minipass@^4.2.4: + version "4.2.8" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-4.2.8.tgz#f0010f64393ecfc1d1ccb5f582bcaf45f48e1a3a" + integrity sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ== + +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0": + version "7.1.3" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.3.tgz#79389b4eb1bb2d003a9bba87d492f2bd37bdc65b" + integrity sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A== + mkdirp@0.3.0: version "0.3.0" resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz" @@ -7399,16 +7754,16 @@ mrmime@^2.0.0: resolved "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz" integrity sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw== -ms@^2.1.3, ms@2.1.3: - version "2.1.3" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - ms@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== +ms@2.1.3, ms@^2.1.3: + version "2.1.3" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + multicast-dns@^7.2.5: version "7.2.5" resolved "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz" @@ -7417,21 +7772,21 @@ multicast-dns@^7.2.5: dns-packet "^5.2.2" thunky "^1.0.2" -nanoid@^3.3.11: - version "3.3.11" - resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz" - integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w== - -negotiator@~0.6.4: - version "0.6.4" - resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz" - integrity sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w== +nanoid@^3.3.12: + version "3.3.15" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.15.tgz#36c490fad8c6e86c824c940dfdde999b69ed4316" + integrity sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA== negotiator@0.6.3: version "0.6.3" resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz" integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== +negotiator@~0.6.4: + version "0.6.4" + resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz" + integrity sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w== + neo-async@^2.6.2: version "2.6.2" resolved "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz" @@ -7455,11 +7810,6 @@ node-emoji@^2.1.0: emojilib "^2.4.0" skin-tone "^2.0.0" -node-forge@^1: - version "1.3.1" - resolved "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz" - integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== - node-releases@^2.0.21: version "2.0.25" resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.25.tgz" @@ -7524,7 +7874,7 @@ object-assign@^4.1.1: resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== -object-inspect@^1.13.3: +object-inspect@^1.13.3, object-inspect@^1.13.4: version "1.13.4" resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz" integrity sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew== @@ -7551,7 +7901,7 @@ obuf@^1.0.0, obuf@^1.1.2: resolved "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz" integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== -on-finished@^2.4.1, on-finished@2.4.1: +on-finished@^2.4.1, on-finished@~2.4.1: version "2.4.1" resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz" integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== @@ -7740,7 +8090,7 @@ pascal-case@^3.1.2: no-case "^3.0.4" tslib "^2.0.3" -path-data-parser@^0.1.0, path-data-parser@0.1.0: +path-data-parser@0.1.0, path-data-parser@^0.1.0: version "0.1.0" resolved "https://registry.npmjs.org/path-data-parser/-/path-data-parser-0.1.0.tgz" integrity sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w== @@ -7765,6 +8115,19 @@ path-parse@^1.0.7: resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== +path-scurry@^1.6.1: + version "1.11.1" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.11.1.tgz#7960a668888594a0720b12a911d1a742ab9f11d2" + integrity sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA== + dependencies: + lru-cache "^10.2.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + +path-to-regexp@3.3.0: + version "3.3.0" + resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.3.0.tgz" + integrity sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw== + path-to-regexp@^1.7.0: version "1.9.0" resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz" @@ -7772,15 +8135,10 @@ path-to-regexp@^1.7.0: dependencies: isarray "0.0.1" -path-to-regexp@0.1.12: - version "0.1.12" - resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz" - integrity sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ== - -path-to-regexp@3.3.0: - version "3.3.0" - resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.3.0.tgz" - integrity sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw== +path-to-regexp@~0.1.12: + version "0.1.13" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.13.tgz#9b22ec16bc3ab88d05a0c7e369869421401ab17d" + integrity sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA== path-type@^4.0.0: version "4.0.0" @@ -7827,7 +8185,19 @@ pkg-types@^2.3.0: exsolve "^1.0.7" pathe "^2.0.3" -points-on-curve@^0.2.0, points-on-curve@0.2.0: +pkijs@^3.3.3: + version "3.4.0" + resolved "https://registry.yarnpkg.com/pkijs/-/pkijs-3.4.0.tgz#d9164def30ff6d97be2d88966d5e36192499ca9c" + integrity sha512-emEcLuomt2j03vxD54giVB4SxTjnsqkU692xZOZXHDVoYyypEm+b3jpiTcc+Cf+myooc+/Ly0z01jqeNHVgJGw== + dependencies: + "@noble/hashes" "1.4.0" + asn1js "^3.0.6" + bytestreamjs "^2.0.1" + pvtsutils "^1.3.6" + pvutils "^1.1.3" + tslib "^2.8.1" + +points-on-curve@0.2.0, points-on-curve@^0.2.0: version "0.2.0" resolved "https://registry.npmjs.org/points-on-curve/-/points-on-curve-0.2.0.tgz" integrity sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A== @@ -8391,12 +8761,12 @@ postcss-zindex@^6.0.2: resolved "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-6.0.2.tgz" integrity sha512-5BxW9l1evPB/4ZIc+2GobEBoKC+h8gPGCMi+jxsYvd2x0mjq7wazk6DrP71pStqxE9Foxh5TVnonbWpFZzXaYg== -"postcss@^7.0.0 || ^8.0.1", postcss@^8, postcss@^8.0.3, postcss@^8.0.9, postcss@^8.1.0, postcss@^8.2.2, postcss@^8.4, postcss@^8.4.21, postcss@^8.4.23, postcss@^8.4.24, postcss@^8.4.31, postcss@^8.4.33, postcss@^8.4.6, postcss@^8.5.4: - version "8.5.6" - resolved "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz" - integrity sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg== +postcss@^8.4.21, postcss@^8.4.24, postcss@^8.4.33, postcss@^8.5.4: + version "8.5.16" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.16.tgz#1230ce0b5df354c24c0ea45f99ce5f6a88279d28" + integrity sha512-vuwillviilfKZsg0VGj5R/YwwcHx4SLsIOI/7K6mQkWx+l5cUHTjj5g0AasTBcyXsbfTgrwsUNmVUb5xVwyPwg== dependencies: - nanoid "^3.3.11" + nanoid "^3.3.12" picocolors "^1.1.1" source-map-js "^1.2.1" @@ -8495,12 +8865,25 @@ pupa@^3.1.0: dependencies: escape-goat "^4.0.0" -qs@6.13.0: - version "6.13.0" - resolved "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz" - integrity sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg== +pvtsutils@^1.3.6: + version "1.3.6" + resolved "https://registry.yarnpkg.com/pvtsutils/-/pvtsutils-1.3.6.tgz#ec46e34db7422b9e4fdc5490578c1883657d6001" + integrity sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg== + dependencies: + tslib "^2.8.1" + +pvutils@^1.1.3, pvutils@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/pvutils/-/pvutils-1.1.5.tgz#84b0dea4a5d670249aa9800511804ee0b7c2809c" + integrity sha512-KTqnxsgGiQ6ZAzZCVlJH5eOjSnvlyEgx1m8bkRJfOhmGRqfo5KLvmAlACQkrjEtOQ4B7wF9TdSLIs9O90MX9xA== + +qs@~6.15.1: + version "6.15.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.15.3.tgz#76852132a58ed5c7c0ef67e4441b9bb5d6061b3b" + integrity sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A== dependencies: - side-channel "^1.0.6" + es-define-property "^1.0.1" + side-channel "^1.1.1" quansync@^0.2.11: version "0.2.11" @@ -8524,30 +8907,25 @@ randombytes@^2.1.0: dependencies: safe-buffer "^5.1.0" -range-parser@^1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz" - integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== - -range-parser@~1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz" - integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== - range-parser@1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz" integrity sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A== -raw-body@2.5.2: - version "2.5.2" - resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz" - integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== +range-parser@^1.2.1, range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@~2.5.3: + version "2.5.3" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.3.tgz#11c6650ee770a7de1b494f197927de0c923822e2" + integrity sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA== dependencies: - bytes "3.1.2" - http-errors "2.0.0" - iconv-lite "0.4.24" - unpipe "1.0.0" + bytes "~3.1.2" + http-errors "~2.0.1" + iconv-lite "~0.4.24" + unpipe "~1.0.0" rc@1.2.8: version "1.2.8" @@ -8559,7 +8937,7 @@ rc@1.2.8: minimist "^1.2.0" strip-json-comments "~2.0.1" -react-dom@*, "react-dom@^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom@^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom@^16.8.4 || ^17 || ^18 || ^19", react-dom@^18.0.0, "react-dom@^18.0.0 || ^19.0.0", "react-dom@>= 16.8.0 < 20.0.0": +react-dom@^18.0.0: version "18.3.1" resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz" integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw== @@ -8605,7 +8983,7 @@ react-loadable-ssr-addon-v5-slorber@^1.0.1: dependencies: "@babel/runtime" "^7.10.3" -react-loadable@*, react-loadable@^5.5.0: +react-loadable@^5.5.0: version "5.5.0" resolved "https://registry.npmjs.org/react-loadable/-/react-loadable-5.5.0.tgz" integrity sha512-C8Aui0ZpMd4KokxRdVAm2bQtI03k2RMRNzOB+IipV3yxFTSVICv7WoUr5L9ALB5BmKO1iHgZtWM8EvYG83otdg== @@ -8644,7 +9022,7 @@ react-router-dom@^5.3.4: tiny-invariant "^1.0.2" tiny-warning "^1.0.0" -react-router@^5.3.4, react-router@>=5, react-router@5.3.4: +react-router@5.3.4, react-router@^5.3.4: version "5.3.4" resolved "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz" integrity sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA== @@ -8659,7 +9037,7 @@ react-router@^5.3.4, react-router@>=5, react-router@5.3.4: tiny-invariant "^1.0.2" tiny-warning "^1.0.0" -react@*, "react@^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react@^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react@^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react@^16.8.4 || ^17 || ^18 || ^19", "react@^18 || ^19 || ^19.0.0-rc", react@^18.0.0, "react@^18.0.0 || ^19.0.0", react@^18.3.1, "react@>= 16.8.0 < 20.0.0", react@>=0.14.9, react@>=15, react@>=16, react@>=16.0.0: +react@^18.0.0: version "18.3.1" resolved "https://registry.npmjs.org/react/-/react-18.3.1.tgz" integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== @@ -8735,6 +9113,11 @@ recma-stringify@^1.0.0: unified "^11.0.0" vfile "^6.0.0" +reflect-metadata@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.2.2.tgz#400c845b6cba87a21f2c65c4aeb158f4fa4d9c5b" + integrity sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q== + regenerate-unicode-properties@^10.2.2: version "10.2.2" resolved "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz" @@ -8974,6 +9357,13 @@ reusify@^1.0.4: resolved "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz" integrity sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw== +rimraf@^4.0.0: + version "4.4.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-4.4.1.tgz#bd33364f67021c5b79e93d7f4fa0568c7c21b755" + integrity sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og== + dependencies: + glob "^9.2.0" + robust-predicates@^3.0.2: version "3.0.2" resolved "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz" @@ -9016,7 +9406,7 @@ rw@1: resolved "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz" integrity sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ== -safe-buffer@^5.1.0, safe-buffer@>=5.1.0, safe-buffer@~5.2.0, safe-buffer@5.2.1: +safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.1.0, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -9036,6 +9426,11 @@ sax@^1.2.4: resolved "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz" integrity sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg== +sax@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.6.0.tgz#da59637629307b97e7c4cb28e080a7bc38560d5b" + integrity sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA== + scheduler@^0.23.2: version "0.23.2" resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz" @@ -9048,16 +9443,7 @@ schema-dts@^1.1.2: resolved "https://registry.npmjs.org/schema-dts/-/schema-dts-1.1.5.tgz" integrity sha512-RJr9EaCmsLzBX2NDiO5Z3ux2BVosNZN5jo0gWgsyKvxKIUL5R3swNvoorulAeL9kLB0iTSX7V6aokhla2m7xbg== -schema-utils@^3.0.0: - version "3.3.0" - resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz" - integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== - dependencies: - "@types/json-schema" "^7.0.8" - ajv "^6.12.5" - ajv-keywords "^3.5.2" - -schema-utils@^3.2.0: +schema-utils@^3.0.0, schema-utils@^3.2.0: version "3.3.0" resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz" integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== @@ -9076,7 +9462,7 @@ schema-utils@^4.0.0, schema-utils@^4.0.1, schema-utils@^4.2.0, schema-utils@^4.3 ajv-formats "^2.1.1" ajv-keywords "^5.1.0" -search-insights@^2.0.0, "search-insights@>= 1 < 3": +search-insights@^2.0.0: version "2.17.3" resolved "https://registry.npmjs.org/search-insights/-/search-insights-2.17.3.tgz" integrity sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ== @@ -9094,13 +9480,13 @@ select-hose@^2.0.0: resolved "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz" integrity sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg== -selfsigned@^2.4.1: - version "2.4.1" - resolved "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz" - integrity sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q== +selfsigned@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-5.5.0.tgz#4c9ab7c7c9f35f18fb6a9882c253eb0e6bd6557b" + integrity sha512-ftnu3TW4+3eBfLRFnDEkzGxSF/10BJBkaLJuBHZX0kiPS7bRdlpZGu6YGt4KngMkdTwJE6MbjavFpqHvqVt+Ew== dependencies: - "@types/node-forge" "^1.3.0" - node-forge "^1" + "@peculiar/x509" "^1.14.2" + pkijs "^3.3.3" semver-diff@^4.0.0: version "4.0.0" @@ -9119,24 +9505,24 @@ semver@^7.3.5, semver@^7.3.7, semver@^7.5.4: resolved "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz" integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== -send@0.19.0: - version "0.19.0" - resolved "https://registry.npmjs.org/send/-/send-0.19.0.tgz" - integrity sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw== +send@~0.19.0, send@~0.19.1: + version "0.19.2" + resolved "https://registry.yarnpkg.com/send/-/send-0.19.2.tgz#59bc0da1b4ea7ad42736fd642b1c4294e114ff29" + integrity sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg== dependencies: debug "2.6.9" depd "2.0.0" destroy "1.2.0" - encodeurl "~1.0.2" + encodeurl "~2.0.0" escape-html "~1.0.3" etag "~1.8.1" - fresh "0.5.2" - http-errors "2.0.0" + fresh "~0.5.2" + http-errors "~2.0.1" mime "1.6.0" ms "2.1.3" - on-finished "2.4.1" + on-finished "~2.4.1" range-parser "~1.2.1" - statuses "2.0.1" + statuses "~2.0.2" serialize-javascript@^6.0.0, serialize-javascript@^6.0.1, serialize-javascript@^6.0.2: version "6.0.2" @@ -9171,15 +9557,15 @@ serve-index@^1.9.1: mime-types "~2.1.17" parseurl "~1.3.2" -serve-static@1.16.2: - version "1.16.2" - resolved "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz" - integrity sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw== +serve-static@~1.16.2: + version "1.16.3" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.16.3.tgz#a97b74d955778583f3862a4f0b841eb4d5d78cf9" + integrity sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA== dependencies: encodeurl "~2.0.0" escape-html "~1.0.3" parseurl "~1.3.3" - send "0.19.0" + send "~0.19.1" set-function-length@^1.2.2: version "1.2.2" @@ -9198,7 +9584,7 @@ setprototypeof@1.1.0: resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz" integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== -setprototypeof@1.2.0: +setprototypeof@1.2.0, setprototypeof@~1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz" integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== @@ -9227,18 +9613,18 @@ shebang-regex@^3.0.0: resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -shell-quote@^1.8.3: - version "1.8.3" - resolved "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz" - integrity sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw== +shell-quote@^1.8.4: + version "1.9.0" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.9.0.tgz#e108b1a136586d5964edb3300016d4bedba0fe57" + integrity sha512-Iov+JwFv/2HcTpcwNMKd8+IWNb8tboQJNQTkAY/LLVK7gGH9jy+LGkVqPxfekHl+yMmiqXszdGWXgkfml7hjqA== -side-channel-list@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz" - integrity sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA== +side-channel-list@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/side-channel-list/-/side-channel-list-1.0.1.tgz#c2e0b5a14a540aebee3bbc6c3f8666cc9b509127" + integrity sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w== dependencies: es-errors "^1.3.0" - object-inspect "^1.13.3" + object-inspect "^1.13.4" side-channel-map@^1.0.1: version "1.0.1" @@ -9261,14 +9647,14 @@ side-channel-weakmap@^1.0.2: object-inspect "^1.13.3" side-channel-map "^1.0.1" -side-channel@^1.0.6: - version "1.1.0" - resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz" - integrity sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw== +side-channel@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.1.1.tgz#ea02c62e05dc4bea67d4442f0fb71ee192f8e0ab" + integrity sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ== dependencies: es-errors "^1.3.0" - object-inspect "^1.13.3" - side-channel-list "^1.0.0" + object-inspect "^1.13.4" + side-channel-list "^1.0.1" side-channel-map "^1.0.1" side-channel-weakmap "^1.0.2" @@ -9353,12 +9739,7 @@ source-map-support@~0.5.20: buffer-from "^1.0.0" source-map "^0.6.0" -source-map@^0.6.0: - version "0.6.1" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -source-map@^0.6.1: +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0: version "0.6.1" resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== @@ -9368,11 +9749,6 @@ source-map@^0.7.0: resolved "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz" integrity sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ== -source-map@~0.6.0: - version "0.6.1" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - space-separated-tokens@^1.0.0: version "1.1.5" resolved "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz" @@ -9426,58 +9802,17 @@ stable@^0.1.8: resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== -statuses@2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" - integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== +statuses@~2.0.1, statuses@~2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.2.tgz#8f75eecef765b5e1cfcdc080da59409ed424e382" + integrity sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw== std-env@^3.7.0: version "3.10.0" resolved "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz" integrity sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg== -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -"string-width@^1.0.2 || 2 || 3 || 4": - version "4.2.3" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^4.1.0: - version "4.2.3" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^4.2.0: - version "4.2.3" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^4.2.3: +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -9495,6 +9830,20 @@ string-width@^5.0.1, string-width@^5.1.2: emoji-regex "^9.2.2" strip-ansi "^7.0.1" +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + stringify-entities@^4.0.0: version "4.0.4" resolved "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz" @@ -9597,17 +9946,17 @@ svg-parser@^2.0.4: resolved "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz" integrity sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ== -svgo@^3.0.2, svgo@^3.2.0: - version "2.8.0" - resolved "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz" - integrity sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg== +svgo@^2.8.0, svgo@^3.0.2, svgo@^3.2.0: + version "2.8.2" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-2.8.2.tgz#8e99b7ba5ac9ed7e3a446063865f61e03223fe6b" + integrity sha512-TyzE4NVGLUFy+H/Uy4N6c3G0HEeprsVfge6Lmq+0FdQQ/zqoVYB62IsBZORsiL+o96s6ff/V6/3UQo/C0cgCAA== dependencies: - "@trysound/sax" "0.2.0" commander "^7.2.0" css-select "^4.1.3" css-tree "^1.1.3" csso "^4.2.0" picocolors "^1.0.0" + sax "^1.5.0" stable "^0.1.8" swr@^2.2.5: @@ -9694,9 +10043,9 @@ to-vfile@^6.1.0: is-buffer "^2.0.0" vfile "^4.0.0" -toidentifier@1.0.1: +toidentifier@~1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== totalist@^3.0.0: @@ -9729,11 +10078,23 @@ ts-dedent@^2.2.0: resolved "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz" integrity sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ== -tslib@^2, tslib@^2.0.0, tslib@^2.0.3, tslib@^2.6.0, tslib@2: +tslib@^1.9.3: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tslib@^2.0.0, tslib@^2.0.3, tslib@^2.6.0, tslib@^2.8.1: version "2.8.1" resolved "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz" integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== +tsyringe@^4.10.0: + version "4.10.0" + resolved "https://registry.yarnpkg.com/tsyringe/-/tsyringe-4.10.0.tgz#d0c95815d584464214060285eaaadd94aa03299c" + integrity sha512-axr3IdNuVIxnaK5XGEUFTu3YmAQ6lllgrvqfEoR16g/HGnYY/6We4oWENtAnzK6/LpJ2ur9PAb80RBt7/U4ugw== + dependencies: + tslib "^1.9.3" + type-fest@^0.21.3: version "0.21.3" resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz" @@ -9764,7 +10125,7 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" -typescript@^4.0.0, typescript@>=4.9.5: +typescript@^4.0.0: version "4.9.5" resolved "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz" integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== @@ -9925,7 +10286,7 @@ universalify@^2.0.0: resolved "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz" integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== -unpipe@~1.0.0, unpipe@1.0.0: +unpipe@~1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== @@ -10157,13 +10518,13 @@ webpack-dev-middleware@^7.4.2: schema-utils "^4.0.0" webpack-dev-server@^5.2.2: - version "5.2.2" - resolved "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.2.2.tgz" - integrity sha512-QcQ72gh8a+7JO63TAx/6XZf/CWhgMzu5m0QirvPfGvptOusAxG12w2+aua1Jkjr7hzaWDnJ2n6JFeexMHI+Zjg== + version "5.2.6" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-5.2.6.tgz#3a5d41233cbb7504f814d19e59a59173fb8ae23d" + integrity sha512-HNLRmamRvVavZQ+avceZifmv8hmdUjg43t6MI4SqJDwFdW7RPQwH5vzGhDRZSX59SgfbeHhLnq3g+uooWo7pVw== dependencies: "@types/bonjour" "^3.5.13" "@types/connect-history-api-fallback" "^1.5.4" - "@types/express" "^4.17.21" + "@types/express" "^4.17.25" "@types/express-serve-static-core" "^4.17.21" "@types/serve-index" "^1.9.4" "@types/serve-static" "^1.15.5" @@ -10173,17 +10534,17 @@ webpack-dev-server@^5.2.2: bonjour-service "^1.2.1" chokidar "^3.6.0" colorette "^2.0.10" - compression "^1.7.4" + compression "^1.8.1" connect-history-api-fallback "^2.0.0" - express "^4.21.2" + express "^4.22.1" graceful-fs "^4.2.6" http-proxy-middleware "^2.0.9" ipaddr.js "^2.1.0" - launch-editor "^2.6.1" + launch-editor "^2.14.1" open "^10.0.3" p-retry "^6.2.0" schema-utils "^4.2.0" - selfsigned "^2.4.1" + selfsigned "^5.5.0" serve-index "^1.9.1" sockjs "^0.3.24" spdy "^4.0.2" @@ -10213,7 +10574,7 @@ webpack-sources@^3.2.3: resolved "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz" integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== -"webpack@^4.0.0 || ^5.0.0", webpack@^5.0.0, webpack@^5.1.0, webpack@^5.20.0, webpack@^5.88.1, webpack@^5.95.0, "webpack@>=4.41.1 || 5.x", webpack@>=5, "webpack@3 || 4 || 5": +webpack@^5.88.1, webpack@^5.95.0: version "5.97.1" resolved "https://registry.npmjs.org/webpack/-/webpack-5.97.1.tgz" integrity sha512-EksG6gFY3L1eFMROS/7Wzgrii5mBAFe4rIr3r2BTfo7bcc+DWwFZ4OJ/miOuHJO/A85HwyI4eQ0F6IKXesO7Fg== @@ -10256,10 +10617,10 @@ webpackbar@^6.0.1: std-env "^3.7.0" wrap-ansi "^7.0.0" -websocket-driver@^0.7.4, websocket-driver@>=0.5.1: - version "0.7.4" - resolved "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz" - integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== +websocket-driver@>=0.5.1, websocket-driver@^0.7.4: + version "0.7.5" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.5.tgz#569d22764ab21f2de20af0e74b411e8ae5a0fa46" + integrity sha512-ZL2+3c7kMBdIRCMz6l8jQMHyGVxj+UL+xVk74Ombiciboca8rHa15L86B19E5oh1pL9Ii/uj54gtsIrZGMo6zA== dependencies: http-parser-js ">=0.5.1" safe-buffer ">=5.1.0" @@ -10373,7 +10734,7 @@ yocto-queue@^1.0.0: resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.1.tgz" integrity sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg== -"zod@^3.25.76 || ^4.1.8", zod@^4.1.8: +zod@^4.1.8: version "4.1.12" resolved "https://registry.npmjs.org/zod/-/zod-4.1.12.tgz" integrity sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==