Skip to content

[seaweedfs] Add External topology - #1231

Closed
Andrei Kvapil (kvaps) wants to merge 2 commits into
mainfrom
seaweedfs-external
Closed

[seaweedfs] Add External topology#1231
Andrei Kvapil (kvaps) wants to merge 2 commits into
mainfrom
seaweedfs-external

Conversation

@kvaps

@kvaps Andrei Kvapil (kvaps) commented Jul 22, 2025

Copy link
Copy Markdown
Member
  • [seaweedfs] Add External topology
  • [seaweedfs] add externalClients support

What this PR does

Release note

[seaweedfs] Add External topology

Summary by CodeRabbit

  • New Features

    • Added support for an "External" topology option, enabling integration with external SeaweedFS clusters.
    • Introduced configuration for defining external clusters to manage bucket claims.
    • Added deployment of external client components and related Kubernetes resources for multi-cluster support.
    • Introduced new Kubernetes RBAC roles, service accounts, and bucket class resources for external topology.
  • Improvements

    • Updated documentation to include the new "External" topology and external cluster parameters.
    • Helm chart templates now conditionally deploy resources based on the selected topology, optimizing "External" deployments.
    • Enhanced validation to prevent unsupported topology changes after initial deployment.

Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
@coderabbitai

coderabbitai Bot commented Jul 22, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

The changes introduce support for an "External" topology option in the SeaweedFS Helm chart, along with related configuration, documentation, and Kubernetes manifests. New parameters and templates facilitate integration with external clusters, conditionally rendering resources and RBAC rules based on the selected topology. Documentation and schema files are updated accordingly.

Changes

File(s) Change Summary
values.schema.json, values.yaml, README.md Added "External" to allowed topology values; introduced externalClients parameter with documentation and schema updates.
templates/cm.yaml New ConfigMap template to store deployed topology value.
templates/dashboard-resourcemap.yaml Conditional Role/RoleBinding logic based on topology; added RoleBinding for "super-admin" subjects.
templates/external-clients/deploy.yaml New template for deploying external SeaweedFS clients and associated Secrets per external client.
templates/external/cosi-bucket-class.yaml New template for BucketClass and BucketAccessClass resources when topology is "External".
templates/external/cosi-cluster-role.yaml New ClusterRole and ClusterRoleBinding templates for external object storage provisioner.
templates/external/cosi-service-account.yaml New ServiceAccount and Secret template for external topology.
templates/external/cosi-deployment.yaml New Deployment template for topology "Client" with driver and sidecar containers.
templates/seaweedfs.yaml Enhanced topology detection logic; conditional rendering of main resources based on topology.
templates/vpa.yaml Wrapped VPA manifest in conditional to exclude when topology is "External".

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Helm
    participant Kubernetes API
    participant External Cluster

    User->>Helm: Install/upgrade SeaweedFS chart with topology="External"
    Helm->>Kubernetes API: Deploy ConfigMap with topology
    Helm->>Kubernetes API: Create ServiceAccount, ClusterRole, ClusterRoleBinding (if External)
    Helm->>Kubernetes API: Deploy external client Deployments and Secrets (per externalClients)
    Helm->>Kubernetes API: Create BucketClass and BucketAccessClass (if External)
    Note over Helm,External Cluster: No main SeaweedFS StatefulSet/Deployment created in "External" mode
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~45 minutes

Suggested reviewers

  • lllamnyp

Poem

In fields of YAML, rabbits hop with glee,
"External" now joins our topology tree!
ConfigMaps and Roles, new clusters in tow,
Secrets and clients, all ready to go.
With charts now more clever and docs up to date,
SeaweedFS hops forward—let’s celebrate!
🐇✨

Note

⚡️ Unit Test Generation - Beta

CodeRabbit's unit test generation is now available in Beta! Automatically generate comprehensive unit tests for your code changes, ensuring better test coverage and catching edge cases you might miss. Our AI analyzes your code structure and creates tests that follow best practices and your project's testing patterns. Learn more here, or just try it under ✨ Finishing Touches.

✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch seaweedfs-external

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary of Changes

Hello Andrei Kvapil (@kvaps), I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the SeaweedFS Helm chart by introducing an "External" topology. This new mode allows the chart to act as a COSI (Container Object Storage Interface) provisioner for existing, externally managed SeaweedFS clusters, rather than deploying a new one. It includes the necessary Kubernetes resources and configuration options to facilitate secure communication and bucket management across different Kubernetes environments, while also adding safeguards to prevent topology changes post-deployment.

Highlights

  • New "External" Topology: Introduced a new External topology option for SeaweedFS deployments. This allows the Helm chart to be deployed in a mode where it doesn't provision its own SeaweedFS cluster, but instead connects to and manages bucketclaims on an existing, external SeaweedFS cluster.
  • External Cluster Integration (COSI): Added comprehensive support for integrating with external SeaweedFS clusters via the Container Object Storage Interface (COSI). This includes new Kubernetes resources like Deployments for the seaweedfs-cosi-driver and seaweedfs-cosi-sidecar, along with necessary BucketClass, BucketAccessClass, ClusterRole, ClusterRoleBinding, ServiceAccount, and Secrets for secure communication.
  • Conditional Component Deployment: Modified the Helm chart to conditionally deploy core SeaweedFS components (master, filer, volume, and VPA) only when the topology is not set to External. This ensures that in the External topology, only the COSI provisioner components are deployed, minimizing resource consumption.
  • Topology Change Prevention: Implemented a mechanism to detect the currently deployed SeaweedFS topology (Simple, MultiZone, or External) by storing it in a ConfigMap. This prevents users from accidentally switching between different topologies after the initial deployment, which could lead to data inconsistencies or operational issues.
  • External Client Configuration: Introduced a new externalClusters parameter in values.yaml and values.schema.json. This parameter allows users to define connection details (such as cluster API endpoint, CA certificate, and service account token) for multiple external Kubernetes clusters where the SeaweedFS COSI drivers will operate.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment Gemini (@gemini-code-assist) Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on Gemini (@gemini-code-assist) comments or fill out our survey to provide feedback.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces an "External" topology for the SeaweedFS chart, enabling connections to an external SeaweedFS instance, and adds externalClients support for managing bucket claims across clusters. While this is a valuable feature, the current implementation has several critical and high-severity issues, including hardcoded namespaces, a significant privilege escalation in RBAC rules, and incorrect resource configurations that will likely cause deployment failures or security vulnerabilities. I've provided specific suggestions to address these issues.

kind: Deployment
metadata:
name: {{ $.Release.Name }}-objectstorage-provisioner-{{ $clientName }}
namespace: tenant-dev

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The namespace for the Deployment is hardcoded to tenant-dev. This will cause the provisioner to be deployed in the wrong namespace. It should be deployed in the release namespace.

  namespace: {{ $.Release.Namespace }}

contexts:
- context:
cluster: {{ $clientName }}
namespace: tenant-hidora

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The namespace in the generated kubeconfig is hardcoded to tenant-hidora. This will cause the provisioner to operate in the wrong namespace in the external cluster. It should use the namespace defined for the client in values.yaml.

        namespace: {{ $client.namespace | quote }}

Comment on lines +9 to 38
- secrets
resourceNames:
- {{ $.Release.Name }}-s3
verbs: ["get", "list", "watch"]
- apiGroups:
- networking.k8s.io
resources:
- ingresses
resourceNames:
- ingress-{{ $.Release.Name }}-s3
verbs: ["get", "list", "watch"]
- apiGroups:
- cozystack.io
resources:
- workloadmonitors
resourceNames:
- {{ $.Release.Name }}-master
- {{ $.Release.Name }}-filer
- {{ $.Release.Name }}-volume
- {{ $.Release.Name }}-db
- {{ .Release.Namespace }}-seaweedfs-objectstorage-provisioner
verbs: ["get", "list", "watch"]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The Role is configured to grant access to a secret named {{ .Release.Namespace }}-seaweedfs-objectstorage-provisioner. This secret is only created when .Values.topology is "External". However, this Role is created for all topologies. This means for "Simple" and "MultiZone" topologies, this Role will point to a non-existent secret. The Role and associated RoleBinding should probably be wrapped in a condition, e.g., {{- if eq .Values.topology \"External\" }}.

name: {{ .Release.Name }}-dashboard-resources
subjects:
{{ include "cozy-lib.rbac.subjectsForTenantAndAccessLevel" (list "admin" .Release.Namespace) }}
{{ include "cozy-lib.rbac.subjectsForTenantAndAccessLevel" (list "super-admin" .Release.Namespace) }}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The access level for dashboard resources is being elevated from admin to super-admin. This is a significant privilege escalation and a potential security risk. Could you please clarify why this change is necessary? If this level of access is not strictly required, it would be better to adhere to the principle of least privilege and revert to admin.

{{ include "cozy-lib.rbac.subjectsForTenantAndAccessLevel" (list "admin" .Release.Namespace) }}

- name: KUBECONFIG
value: /kubeconfig
- name: POD_NAMESPACE
value: tenant-root

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The POD_NAMESPACE environment variable is hardcoded to tenant-root. This is likely incorrect and could cause issues with the controller's operation (e.g., for leader election or event creation). It should be set to the namespace where the pod is running, which is the release namespace.

          value: {{ $.Release.Namespace }}

apiVersion: objectstorage.k8s.io/v1alpha1
metadata:
name: {{ .Release.Namespace }}
driverName: {{ .Release.Namespace }}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The driverName for the BucketAccessClass appears to be incorrect. It is set to {{ .Release.Namespace }}, but it should match the driverName of the COSI driver. Based on the BucketClass in this file and the driver configuration, it should be {{ .Release.Namespace }}.seaweedfs.objectstorage.k8s.io.

driverName: {{ .Release.Namespace }}.seaweedfs.objectstorage.k8s.io

Comment thread packages/extra/seaweedfs/README.md Outdated
| `size` | Persistent Volume size | `10Gi` |
| `storageClass` | StorageClass used to store the data | `""` |
| `zones` | A map of zones for MultiZone topology. Each zone can have its own number of replicas and size. | `{}` |
| `externalClusters` | object A map of external clusters for managing bucketclaims. | `{}` |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The description for externalClusters starts with "object". This seems to be a type hint that has leaked into the documentation. For better readability, it should be removed.

Suggested change
| `externalClusters` | object A map of external clusters for managing bucketclaims. | `{}` |
| `externalClusters` | A map of external clusters for managing bucketclaims. | `{}` |

Comment thread packages/extra/seaweedfs/values.yaml Outdated
## size: 10Gi
zones: {}

## @param externalClusters object A map of external clusters for managing bucketclaims.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The description for externalClusters starts with "object". This seems to be a type hint that has leaked into the documentation. For better readability, it should be removed.

## @param externalClusters A map of external clusters for managing bucketclaims.

@kvaps
Andrei Kvapil (kvaps) force-pushed the seaweedfs-external branch 2 times, most recently from c179137 to 60b72fa Compare July 22, 2025 13:59

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

♻️ Duplicate comments (3)
packages/extra/seaweedfs/README.md (1)

16-16: Remove leaked “object” type hint to unblock CI

make generate failed because the line still contains the stray word “object”. Drop it so the description reads naturally:

-| `externalClusters`  | object A map of external clusters for managing bucketclaims.                                           | `{}`     |
+| `externalClusters`  | A map of external clusters for managing bucketclaims.                                                 | `{}`     |
packages/extra/seaweedfs/templates/dashboard-resourcemap.yaml (1)

52-63: Duplicate RoleBinding names will break kubectl apply

Both RoleBindings are called {{ .Release.Name }}-dashboard-resources.
Kubernetes forbids two objects with the same kind/name in one namespace; the second apply will fail.

-metadata:
-  name: {{ .Release.Name }}-dashboard-resources
+metadata:
+  name: {{ .Release.Name }}-dashboard-resources-superadmin

(Adjust roleRef/subjects accordingly.)

Also reconsider the privilege escalation to super-admin flagged in earlier review unless strictly required.

packages/extra/seaweedfs/templates/external/cosi-bucket-class.yaml (1)

1-16: YAML invalid & driverName mismatch

  1. driverName/deletionPolicy (BucketClass) and driverName/authenticationType (BucketAccessClass) must live under spec: per COSI API.
  2. BucketAccessClass.driverName should match BucketClass (<ns>.seaweedfs.objectstorage.k8s.io), not just the namespace.
  3. Static analysis flags a top-level --- after a template directive – indentation must start at column 0.

Minimal fix:

---
kind: BucketClass
apiVersion: objectstorage.k8s.io/v1alpha1
metadata:
  name: {{ .Release.Namespace }}
-spec:
-  driverName: {{ .Release.Namespace }}.seaweedfs.objectstorage.k8s.io
-  deletionPolicy: Delete
+spec:
+  driverName: {{ .Release.Namespace }}.seaweedfs.objectstorage.k8s.io
+  deletionPolicy: Delete
---
kind: BucketAccessClass
apiVersion: objectstorage.k8s.io/v1alpha1
metadata:
  name: {{ .Release.Namespace }}
-spec:
-  driverName: {{ .Release.Namespace }}
-  authenticationType: KEY
+spec:
+  driverName: {{ .Release.Namespace }}.seaweedfs.objectstorage.k8s.io
+  authenticationType: KEY

Without these changes Flux will render invalid YAML and COSI will refuse the objects.

🧹 Nitpick comments (3)
packages/extra/seaweedfs/Makefile (1)

5-8: Enum reinjection looks good but consider co-locating all post-processing here

The yq line correctly puts the "External" value back into values.schema.json (👍 for following the readme-generator quirk we’ve seen before).

If we ever need to patch other schema bits (e.g. defaults for externalClusters) they should live in the same recipe so make generate remains the single source of truth. That keeps the build deterministic and avoids hidden drift.

packages/extra/seaweedfs/templates/cm.yaml (1)

3-5: Set namespace explicitly for clarity

Although Helm will default resources into the release namespace, adding it explicitly avoids surprises when the chart is templated without --namespace or in GitOps diff tools.

 metadata:
   name: {{ .Release.Name }}-deployed-topology
+  namespace: {{ .Release.Namespace }}
packages/extra/seaweedfs/templates/external-clients/deploy.yaml (1)

87-88: Pin the sidecar image to a version tag rather than latest

Using :latest@sha256… hampers reproducibility and cache efficiency. Prefer a semver tag (e.g. v0.4.1) together with the digest.

- image: ghcr.io/cozystack/cozystack/objectstorage-controller:latest@sha256:…
+ image: ghcr.io/cozystack/cozystack/objectstorage-controller:v0.4.1@sha256:…
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 65e3b74 and 60b72fa.

📒 Files selected for processing (12)
  • packages/extra/seaweedfs/Makefile (1 hunks)
  • packages/extra/seaweedfs/README.md (1 hunks)
  • packages/extra/seaweedfs/templates/cm.yaml (1 hunks)
  • packages/extra/seaweedfs/templates/dashboard-resourcemap.yaml (3 hunks)
  • packages/extra/seaweedfs/templates/external-clients/deploy.yaml (1 hunks)
  • packages/extra/seaweedfs/templates/external/cosi-bucket-class.yaml (1 hunks)
  • packages/extra/seaweedfs/templates/external/cosi-cluster-role.yaml (1 hunks)
  • packages/extra/seaweedfs/templates/external/cosi-service-account.yaml (1 hunks)
  • packages/extra/seaweedfs/templates/seaweedfs.yaml (3 hunks)
  • packages/extra/seaweedfs/templates/vpa.yaml (2 hunks)
  • packages/extra/seaweedfs/values.schema.json (2 hunks)
  • packages/extra/seaweedfs/values.yaml (2 hunks)
🧠 Learnings (4)
packages/extra/seaweedfs/Makefile (1)

Learnt from: NickVolynkin
PR: #1196
File: packages/apps/http-cache/Makefile:24-27
Timestamp: 2025-07-14T16:23:12.803Z
Learning: In the cozystack repository, the readme-generator tool removes enum contents from values.schema.json files during its operation. Therefore, when using readme-generator in Makefiles, any enum values need to be injected back into the schema using yq commands after readme-generator has run, not before.

packages/extra/seaweedfs/values.schema.json (1)

Learnt from: NickVolynkin
PR: #1196
File: packages/apps/http-cache/Makefile:24-27
Timestamp: 2025-07-14T16:23:12.803Z
Learning: In the cozystack repository, the readme-generator tool removes enum contents from values.schema.json files during its operation. Therefore, when using readme-generator in Makefiles, any enum values need to be injected back into the schema using yq commands after readme-generator has run, not before.

packages/extra/seaweedfs/templates/dashboard-resourcemap.yaml (1)

Learnt from: lllamnyp
PR: #1161
File: packages/apps/virtual-machine/templates/dashboard-resourcemap.yaml:6-12
Timestamp: 2025-07-10T12:14:27.197Z
Learning: Kubernetes RBAC rules with resourceNames work correctly for list/watch verbs. When resourceNames is specified in an RBAC rule, it properly restricts access to only those named resources, even for list and watch operations. Examples: kubectl get resource resourcename -w watches for changes on a single resource, and kubectl get resource --field-selector .metadata.name=resourcename lists a specific resource. The Kubernetes API server correctly distinguishes such requests from their less specific counterparts.

packages/extra/seaweedfs/templates/seaweedfs.yaml (1)

Learnt from: lllamnyp
PR: #1160
File: packages/system/hetzner-robotlb/charts/robotlb/templates/role.yaml:6-8
Timestamp: 2025-07-11T06:28:13.696Z
Learning: In Helm templates, the {{- directive chomps all leading whitespace including newlines back to the previous content, so {{- toYaml .Values.something | nindent 2 }} will render correctly even with apparent indentation issues. However, for better style, it's cleaner to put the template directive on the same line as the parent key (e.g., rules: {{- toYaml .Values.serviceAccount.permissions | nindent 2 }}).

🪛 GitHub Actions: Pre-Commit Checks
packages/extra/seaweedfs/README.md

[error] 13-13: Make generate step failed due to modification of README.md by the hook. The line with 'externalClusters' was changed from 'object A map of external clusters for managing bucketclaims.' to 'A map of external clusters for managing bucketclaims.'. Please commit the updated file.

packages/extra/seaweedfs/values.schema.json

[error] 2-8: Make generate step failed due to modification of values.schema.json by the hook. The description for 'externalClusters' was changed from 'object A map of external clusters for managing bucketclaims.' to 'A map of external clusters for managing bucketclaims.'. Please commit the updated file.

🪛 YAMLlint (1.37.1)
packages/extra/seaweedfs/templates/vpa.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/extra/seaweedfs/templates/cm.yaml

[error] 4-4: syntax error: expected , but found ''

(syntax)

packages/extra/seaweedfs/templates/external/cosi-service-account.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/extra/seaweedfs/templates/external/cosi-bucket-class.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/extra/seaweedfs/templates/seaweedfs.yaml

[warning] 20-20: too many spaces after hyphen

(hyphens)


[warning] 22-22: too many spaces after hyphen

(hyphens)


[warning] 23-23: too many spaces after hyphen

(hyphens)


[warning] 24-24: too many spaces after hyphen

(hyphens)


[warning] 25-25: too many spaces after hyphen

(hyphens)


[warning] 26-26: too many spaces after hyphen

(hyphens)


[warning] 30-30: too many spaces after hyphen

(hyphens)

packages/extra/seaweedfs/values.yaml

[error] 38-38: trailing spaces

(trailing-spaces)

packages/extra/seaweedfs/templates/external/cosi-cluster-role.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)


[warning] 19-19: wrong indentation: expected 2 but found 4

(indentation)


[warning] 28-28: wrong indentation: expected 2 but found 4

(indentation)


[warning] 36-36: wrong indentation: expected 2 but found 4

(indentation)


[warning] 39-39: wrong indentation: expected 2 but found 4

(indentation)


[warning] 52-52: wrong indentation: expected 0 but found 2

(indentation)

packages/extra/seaweedfs/templates/external-clients/deploy.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

🪛 Gitleaks (8.27.2)
packages/extra/seaweedfs/values.yaml

53-53: Uncovered a JSON Web Token, which may lead to unauthorized access to web applications and sensitive user data.

(jwt)

🧰 Additional context used
🧠 Learnings (4)
packages/extra/seaweedfs/Makefile (1)

Learnt from: NickVolynkin
PR: #1196
File: packages/apps/http-cache/Makefile:24-27
Timestamp: 2025-07-14T16:23:12.803Z
Learning: In the cozystack repository, the readme-generator tool removes enum contents from values.schema.json files during its operation. Therefore, when using readme-generator in Makefiles, any enum values need to be injected back into the schema using yq commands after readme-generator has run, not before.

packages/extra/seaweedfs/values.schema.json (1)

Learnt from: NickVolynkin
PR: #1196
File: packages/apps/http-cache/Makefile:24-27
Timestamp: 2025-07-14T16:23:12.803Z
Learning: In the cozystack repository, the readme-generator tool removes enum contents from values.schema.json files during its operation. Therefore, when using readme-generator in Makefiles, any enum values need to be injected back into the schema using yq commands after readme-generator has run, not before.

packages/extra/seaweedfs/templates/dashboard-resourcemap.yaml (1)

Learnt from: lllamnyp
PR: #1161
File: packages/apps/virtual-machine/templates/dashboard-resourcemap.yaml:6-12
Timestamp: 2025-07-10T12:14:27.197Z
Learning: Kubernetes RBAC rules with resourceNames work correctly for list/watch verbs. When resourceNames is specified in an RBAC rule, it properly restricts access to only those named resources, even for list and watch operations. Examples: kubectl get resource resourcename -w watches for changes on a single resource, and kubectl get resource --field-selector .metadata.name=resourcename lists a specific resource. The Kubernetes API server correctly distinguishes such requests from their less specific counterparts.

packages/extra/seaweedfs/templates/seaweedfs.yaml (1)

Learnt from: lllamnyp
PR: #1160
File: packages/system/hetzner-robotlb/charts/robotlb/templates/role.yaml:6-8
Timestamp: 2025-07-11T06:28:13.696Z
Learning: In Helm templates, the {{- directive chomps all leading whitespace including newlines back to the previous content, so {{- toYaml .Values.something | nindent 2 }} will render correctly even with apparent indentation issues. However, for better style, it's cleaner to put the template directive on the same line as the parent key (e.g., rules: {{- toYaml .Values.serviceAccount.permissions | nindent 2 }}).

🪛 GitHub Actions: Pre-Commit Checks
packages/extra/seaweedfs/README.md

[error] 13-13: Make generate step failed due to modification of README.md by the hook. The line with 'externalClusters' was changed from 'object A map of external clusters for managing bucketclaims.' to 'A map of external clusters for managing bucketclaims.'. Please commit the updated file.

packages/extra/seaweedfs/values.schema.json

[error] 2-8: Make generate step failed due to modification of values.schema.json by the hook. The description for 'externalClusters' was changed from 'object A map of external clusters for managing bucketclaims.' to 'A map of external clusters for managing bucketclaims.'. Please commit the updated file.

🪛 YAMLlint (1.37.1)
packages/extra/seaweedfs/templates/vpa.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/extra/seaweedfs/templates/cm.yaml

[error] 4-4: syntax error: expected , but found ''

(syntax)

packages/extra/seaweedfs/templates/external/cosi-service-account.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/extra/seaweedfs/templates/external/cosi-bucket-class.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/extra/seaweedfs/templates/seaweedfs.yaml

[warning] 20-20: too many spaces after hyphen

(hyphens)


[warning] 22-22: too many spaces after hyphen

(hyphens)


[warning] 23-23: too many spaces after hyphen

(hyphens)


[warning] 24-24: too many spaces after hyphen

(hyphens)


[warning] 25-25: too many spaces after hyphen

(hyphens)


[warning] 26-26: too many spaces after hyphen

(hyphens)


[warning] 30-30: too many spaces after hyphen

(hyphens)

packages/extra/seaweedfs/values.yaml

[error] 38-38: trailing spaces

(trailing-spaces)

packages/extra/seaweedfs/templates/external/cosi-cluster-role.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)


[warning] 19-19: wrong indentation: expected 2 but found 4

(indentation)


[warning] 28-28: wrong indentation: expected 2 but found 4

(indentation)


[warning] 36-36: wrong indentation: expected 2 but found 4

(indentation)


[warning] 39-39: wrong indentation: expected 2 but found 4

(indentation)


[warning] 52-52: wrong indentation: expected 0 but found 2

(indentation)

packages/extra/seaweedfs/templates/external-clients/deploy.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

🪛 Gitleaks (8.27.2)
packages/extra/seaweedfs/values.yaml

53-53: Uncovered a JSON Web Token, which may lead to unauthorized access to web applications and sensitive user data.

(jwt)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Prepare environment
🔇 Additional comments (7)
packages/extra/seaweedfs/templates/vpa.yaml (1)

1-1: YAMLlint warning is a false positive – no action required

The template directive on line 1 confuses YAMLlint; Helm will render valid YAML. Nothing to fix here.

packages/extra/seaweedfs/templates/external/cosi-service-account.yaml (1)

9-16: Verify manual SA token Secret does not clash with auto-generated secrets

Creating a kubernetes.io/service-account-token Secret with the same name as the ServiceAccount can be brittle:

  1. On clusters < v1.24 the controller still auto-creates a token Secret (name <sa>-token-xxxxx) – you’re safe.
  2. On ≥ v1.24 the SA token projection API is preferred and no Secret is auto-generated. In that case this template must remain, but the Secret will have empty data until the TokenRequest controller fills it, which requires extra annotations (kubernetes.io/service-account.name is present ✅).

Please double-check on your target Kubernetes versions that:

  • No duplicate token Secrets appear.
  • The manually created Secret actually receives a token field after creation.

If issues arise we may need to switch to a ServiceAccount + kubectl create token flow or use projected volume mounts instead.

packages/extra/seaweedfs/values.schema.json (1)

34-41: Enum update looks good

"External" is correctly appended to the enum list and description.

packages/extra/seaweedfs/templates/dashboard-resourcemap.yaml (1)

6-39: Conditional rules resolved the missing-secret issue – nice
Wrapping the secret rule in if eq .Values.topology "External" prevents invalid RBAC on non-external installs.

packages/extra/seaweedfs/templates/seaweedfs.yaml (1)

17-31: Topology-switch guard is solid

The added ConfigMap-based detection and prevention of topology changes after first install is a good safety net.

packages/extra/seaweedfs/templates/external/cosi-cluster-role.yaml (1)

1-1: YAML-lint error is a false positive

The linter complains about a “syntax error” at line 1 because it parses the Go-template directive {{- if … }} as raw YAML. The rendered manifest is valid; no action required.

packages/extra/seaweedfs/templates/external-clients/deploy.yaml (1)

111-125: Secrets referenced do not exist in the client namespace

The pod mounts a series of secrets ({{ $.Release.Name }}-*-cert) but these are created only in the release namespace, not in $client.namespace.
Either:

  1. Create mirrored secrets in each client namespace, or
  2. Switch to secretName: {{ $.Release.Namespace }}/… with a projected volume that supports cross-namespace refs (not currently available), or
  3. Deploy the pods in the release namespace instead.

Without this, the Deployment will stay in CreateContainerConfigError.

Comment on lines +1 to +3
{{- $myNS := lookup "v1" "Namespace" "" .Release.Namespace }}
{{- $ingress := index $myNS.metadata.annotations "namespace.cozystack.io/ingress" }}
{{- $host := index $myNS.metadata.annotations "namespace.cozystack.io/host" }}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

lookup may return nil – guard against Helm template panic

When helm template is rendered offline (or against an API server that does not yet contain the namespace object), lookup returns nil.
Referencing $myNS.metadata.annotations without a nil-check will cause template: runtime error: invalid memory address.

-{{- $ingress := index $myNS.metadata.annotations "namespace.cozystack.io/ingress" }}
-{{- $host := index $myNS.metadata.annotations "namespace.cozystack.io/host" }}
+{{- if $myNS }}
+  {{- $ingress := index $myNS.metadata.annotations "namespace.cozystack.io/ingress" }}
+  {{- $host := index $myNS.metadata.annotations "namespace.cozystack.io/host" }}
+{{- else }}
+  {{- $ingress := "" }}
+  {{- $host := "" }}
+{{- end }}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{{- $myNS := lookup "v1" "Namespace" "" .Release.Namespace }}
{{- $ingress := index $myNS.metadata.annotations "namespace.cozystack.io/ingress" }}
{{- $host := index $myNS.metadata.annotations "namespace.cozystack.io/host" }}
{{- $myNS := lookup "v1" "Namespace" "" .Release.Namespace }}
{{- if $myNS }}
{{- $ingress := index $myNS.metadata.annotations "namespace.cozystack.io/ingress" }}
{{- $host := index $myNS.metadata.annotations "namespace.cozystack.io/host" }}
{{- else }}
{{- $ingress := "" }}
{{- $host := "" }}
{{- end }}
🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

🤖 Prompt for AI Agents
In packages/extra/seaweedfs/templates/external-clients/deploy.yaml at lines 1 to
3, the code uses the lookup function to get a namespace object but does not
check if the result is nil before accessing metadata.annotations, which can
cause a runtime panic. To fix this, add a conditional check to ensure $myNS is
not nil before accessing its metadata.annotations fields, and provide fallback
values or handle the nil case gracefully to avoid template rendering errors.

Comment on lines +33 to +35
spec:
containers:
- name: seaweedfs-cosi-driver

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Missing serviceAccountName – pods will run with the default SA and lack RBAC

The Deployment omits serviceAccountName. As a result the driver & sidecar inherit the default service account of $client.namespace, which has no permissions.
Set it explicitly to the service account bound in the ClusterRoleBinding (or create one per client namespace):

 spec:
   serviceAccountName: {{ $.Release.Namespace }}-seaweedfs-objectstorage-provisioner
   containers:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
spec:
containers:
- name: seaweedfs-cosi-driver
spec:
serviceAccountName: {{ $.Release.Namespace }}-seaweedfs-objectstorage-provisioner
containers:
- name: seaweedfs-cosi-driver
🤖 Prompt for AI Agents
In packages/extra/seaweedfs/templates/external-clients/deploy.yaml around lines
33 to 35, the Deployment spec is missing the serviceAccountName field, causing
pods to run with the default service account that lacks necessary RBAC
permissions. Add the serviceAccountName field under the spec section and set it
to the appropriate service account name that is bound in the ClusterRoleBinding
or create a dedicated service account per client namespace to ensure the driver
and sidecar have the required permissions.

Comment on lines +107 to +108
- name: socket
- configMap:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

socket volume has no source – manifest will be rejected by the API server

A volume definition must specify a source (emptyDir, hostPath, etc.). Add an emptyDir: {} to make it a transient in-pod volume:

 - name: socket
+  emptyDir: {}

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In packages/extra/seaweedfs/templates/external-clients/deploy.yaml at lines
107-108, the volume named "socket" lacks a source definition, causing the
manifest to be rejected by the API server. Fix this by adding an "emptyDir: {}"
field under the "socket" volume to define it as a transient in-pod volume.

Comment on lines +34 to +45
- apiGroups: [""]
resources:
- "secrets"
- "events"
verbs:
- "get"
- "list"
- "watch"
- "update"
- "create"
- "delete"
- "patch"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Secrets permissions are overly broad – scope down or risk cluster-wide compromise

Granting create, update, delete, and patch on all Secrets in a ClusterRole exposes every namespace to accidental or malicious secret tampering by the object-storage provisioner.
Unless the controller really needs to mint / rotate secrets in every namespace, switch to:

  1. A namespaced Role/RoleBinding, or
  2. A ClusterRole limited to get, list, watch on Secrets and a namespace-scoped Role for the write verbs where strictly required.

Diff sketch:

-  verbs:
-    - "get"
-    - "list"
-    - "watch"
-    - "update"
-    - "create"
-    - "delete"
-    - "patch"
+  verbs: ["get", "list", "watch"]   # write verbs moved to a namespaced Role
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- apiGroups: [""]
resources:
- "secrets"
- "events"
verbs:
- "get"
- "list"
- "watch"
- "update"
- "create"
- "delete"
- "patch"
- apiGroups: [""]
resources:
- "secrets"
- "events"
verbs: ["get", "list", "watch"] # write verbs moved to a namespaced Role
🧰 Tools
🪛 YAMLlint (1.37.1)

[warning] 36-36: wrong indentation: expected 2 but found 4

(indentation)


[warning] 39-39: wrong indentation: expected 2 but found 4

(indentation)

🤖 Prompt for AI Agents
In packages/extra/seaweedfs/templates/external/cosi-cluster-role.yaml between
lines 34 and 45, the ClusterRole grants overly broad permissions on all Secrets,
including create, update, delete, and patch, which risks cluster-wide secret
compromise. To fix this, remove the write verbs (create, update, delete, patch)
from this ClusterRole and limit it to read-only verbs (get, list, watch) on
Secrets. Then, create a separate namespaced Role and RoleBinding that grants the
necessary write permissions only in the specific namespaces where secret
modification is required.

Comment on lines +3 to +7
"externalClusters": {
"default": {},
"description": "object A map of external clusters for managing bucketclaims.",
"type": "object"
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix failing pre-commit: remove stray “object” prefix from description

pre-commit rewrote the file because the description now starts with "object A map...".
Drop the leaked type hint so the hook stops modifying the file:

-      "description": "object A map of external clusters for managing bucketclaims.",
+      "description": "A map of external clusters for managing bucketclaims.",

Re-run make generate and commit the regenerated schema.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"externalClusters": {
"default": {},
"description": "object A map of external clusters for managing bucketclaims.",
"type": "object"
},
"externalClusters": {
"default": {},
"description": "A map of external clusters for managing bucketclaims.",
"type": "object"
},
🤖 Prompt for AI Agents
In packages/extra/seaweedfs/values.schema.json around lines 3 to 7, the
description for "externalClusters" incorrectly starts with the word "object"
which is a stray type hint causing pre-commit to fail. Remove the leading
"object" from the description so it reads as "A map of external clusters for
managing bucketclaims." After fixing the description, re-run `make generate` to
regenerate the schema and commit the updated file.

Comment thread packages/extra/seaweedfs/values.yaml Outdated
Comment on lines +35 to +54
## @param externalClusters A map of external clusters for managing bucketclaims.
## Example:
## externalClusters:
## cluster1:
## cluster: "https://api.example.org"
## namespace: "tenant-root"
## ca: |
## -----BEGIN CERTIFICATE-----
## MIIBijCCATCgAwIBAgIRAMg6nrACqxg97aDuhzrpqGMwCgYIKoZIzj0EAwIwFTET
## MBEGA1UEChMKa3ViZXJuZXRlczAeFw0yNTA1MTUwNzE5MTBaFw0zNTA1MTMwNzE5
## MTBaMBUxEzARBgNVBAoTCmt1YmVybmV0ZXMwWTATBgcqhkjOPQIBBggqhkjOPQMB
## BwNCAATh2nTL8tglw2cHO3/QSMqsiP4Ws8UIxNxjG5MtmIx4E7EH9fJjcpx6Ncfg
## Ekq6lbeTi6KpQOksAvhiq/EcwLLUo2EwXzAOBgNVHQ8BAf8EBAMCAoQwHQYDVR0l
## BBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O
## BBYEFEwtnxdCdotUI1cbgsszGHM/nbUuMAoGCCqGSM49BAMCA0gAMEUCIQCA785y
## 6H6l8T1r0HjhAkHqWWYpuPj8lhiSqG0aXinWPgIgPksSKIRTnVyiQ/w5pWMnKuBD
## QFq6nUXbcO+ABY439FU=
## -----END CERTIFICATE-----
## token: "eyJhbGciOiJSUzI1NiIsImtpZCI6IlJMaEMyMTVvdDVVSENqZ1EySEFtVUhobnp2Mi02RXJ4bWM0bDJVenJmYzgifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJ0ZW5hbnQtcm9vdCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJ0ZW5hbnQtcm9vdCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJ0ZW5hbnQtcm9vdCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6ImQ4OWRmN2M0LTI1OTctNGQ0NS1hM2U4LTIzMWVhYTJiN2U5NCIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDp0ZW5hbnQtcm9vdDp0ZW5hbnQtcm9vdCJ9.eIFJwuT5q4nxgsTraxTw7cnaMiKaOOTpFazSf_LKS_gE9KO6AC5WvitFFIMudnm_0XrYMrMbjoBvtNf3khzmy-n5WSmmlxyZj0RKUUgoWnVjwy2pq0xLiZWSzbrHKnDpfyYUgz6Qz-LcqNK5O6Mnkd5xpz2FrY3vdjLJJ90f3cKFewI3GksvI6F7NG7ANSdhI0xBVKCCsIGoQL1m7ieTQtJoS9p4HtlfTBFOHj6NCu4Sai-2z-CC_cVxYQLCPD3fsYTpF4MZGMunDHaHadMVmvBZrHyBdH4OcrCGJ2ZtXBOsxxYRq8SHsGP7M5T_jwZ8j66BtJ_d3-3Aij-lorX2dpmwBLcc1yR5Pxgh1bwjRn_04oM30s6xlVcpupAfTvs4WpApADKsV3RixLTYNf18mTCpZL6phbw3TWSRSD0Gz-08QkROWvB2IJqsya65BPnSfab5eFumYvYiZVn84mHhh7BxSuRXBTTGAYzQ-D6t1V7W2sSPF191lrSkYkxwQ_rtyi4EfDqayD2D4pFGWJJhqSM7Ra4ZsAy9TpSTfKtWsIwngwnGn7zXsWKPIYGP8Xyt-97nWum4qvgHQAPBa0SofxI7dKHiZ1KKo-vOuKdL0Qka0_E-h_3w1w3Gn6-q1X8qp5YNB-fHooYYGeL8kFiBjRacB1QSAGAuBwaKl37xB4U"
externalClusters: {}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Replace real-looking JWT & trim trailing whitespace in example block

  1. A full JWT (line 53) is checked into the repo—even though it sits in a commented example, it will still be harvested by scanners and triggers Gitleaks.
  2. YAML-lint flags trailing spaces on the example lines (e.g. line 38).

Consider sanitising the token and tidying whitespace:

-##     token: "eyJhbGciOiJSUzI1NiIsImtpZCI6IlJMaEMyMTVvdDVVSENqZ1EySEFtVUhobnp2Mi02RXJ4bWM0bDJVenJmYzgifQ...
+##     # token: "<REDACTED>"

(or delete the token line entirely).

Cleaning the example prevents accidental secret leakage and lets the pre-commit hooks pass.

🧰 Tools
🪛 Gitleaks (8.27.2)

53-53: Uncovered a JSON Web Token, which may lead to unauthorized access to web applications and sensitive user data.

(jwt)

🪛 YAMLlint (1.37.1)

[error] 38-38: trailing spaces

(trailing-spaces)

🤖 Prompt for AI Agents
In packages/extra/seaweedfs/values.yaml between lines 35 and 54, the example
block contains a real-looking JWT token and trailing whitespace that causes
linting errors and potential secret leakage. Replace the JWT token with a
clearly sanitized placeholder or remove the token line entirely, and remove any
trailing spaces on the example lines to ensure the YAML is clean and passes
pre-commit checks.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (5)
packages/extra/seaweedfs/templates/external/cosi-cluster-role.yaml (1)

36-47: Secret write verbs are still present – high-risk cluster-wide exposure

The ClusterRole continues to grant create / update / delete / patch on every Secret in the cluster.
That is an unnecessary escalation for an object-storage provisioner and was already called out in the earlier review.

   resources:
     - "secrets"
     - "events"
   verbs:
-    - "get"
-    - "list"
-    - "watch"
-    - "update"
-    - "create"
-    - "delete"
-    - "patch"
+    - "get"
+    - "list"
+    - "watch"

If write access to Secrets is absolutely required, move those verbs to a namespaced Role scoped only to the namespaces where secret mutation is unavoidable.

packages/extra/seaweedfs/templates/external-clients/deploy.yaml (4)

1-3: lookup nil-safety missing – template panics when the Namespace object is absent

lookup returns nil when rendering against an API server (or helm template) without the Namespace.
Accessing .metadata.annotations on nil causes a hard failure.

-{{- $ingress := index $myNS.metadata.annotations "namespace.cozystack.io/ingress" }}
-{{- $host := index $myNS.metadata.annotations "namespace.cozystack.io/host" }}
+{{- $ingress := "" }}
+{{- $host := "" }}
+{{- if $myNS }}
+  {{- $ingress = index $myNS.metadata.annotations "namespace.cozystack.io/ingress" | default "" }}
+  {{- $host    = index $myNS.metadata.annotations "namespace.cozystack.io/host"    | default "" }}
+{{- end }}

34-35: Pods will run under the default ServiceAccount – RBAC rules won’t apply

serviceAccountName is missing. The containers therefore inherit the default SA and lack the ClusterRoleBinding you created.

 spec:
+  serviceAccountName: {{ $.Release.Namespace }}-seaweedfs-objectstorage-provisioner
   containers:

95-97: POD_NAMESPACE env var should reflect the running pod’s namespace, not the remote client

Hard-coding $client.namespace misleads components that rely on this variable (leader-election, event creation, metrics labels).

-          value: {{ $client.namespace }}
+          valueFrom:
+            fieldRef:
+              fieldPath: metadata.namespace

108-109: socket volume lacks a source – manifest will be rejected by the API server

name alone is insufficient; add emptyDir: {} (or another source) to make it a valid volume spec.

 - name: socket
+  emptyDir: {}
🧹 Nitpick comments (1)
packages/extra/seaweedfs/templates/external/cosi-cluster-role.yaml (1)

20-35: Indentation does not match YAML spec – template renders but fails helm lint

The verbs arrays are indented with 4 spaces beneath their parent key, while the preceding keys are at 2-space depth.
Helm will happily render the manifest, but helm lint / yamllint report errors and downstream automation may reject the file.

-  verbs:
-      - "get"
-      - "list"
+  verbs:
+    - "get"
+    - "list"

Apply the same 2-space indentation to all verbs: blocks for consistency.

Also applies to: 40-47

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4e05160 and 97fa149.

📒 Files selected for processing (2)
  • packages/extra/seaweedfs/templates/external-clients/deploy.yaml (1 hunks)
  • packages/extra/seaweedfs/templates/external/cosi-cluster-role.yaml (1 hunks)
🧠 Learnings (1)
packages/extra/seaweedfs/templates/external-clients/deploy.yaml (1)

Learnt from: lllamnyp
PR: #1160
File: packages/system/hetzner-robotlb/charts/robotlb/templates/role.yaml:6-8
Timestamp: 2025-07-11T06:28:13.696Z
Learning: In Helm templates, the {{- directive chomps all leading whitespace including newlines back to the previous content, so {{- toYaml .Values.something | nindent 2 }} will render correctly even with apparent indentation issues. However, for better style, it's cleaner to put the template directive on the same line as the parent key (e.g., rules: {{- toYaml .Values.serviceAccount.permissions | nindent 2 }}).

🪛 YAMLlint (1.37.1)
packages/extra/seaweedfs/templates/external-clients/deploy.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/extra/seaweedfs/templates/external/cosi-cluster-role.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)


[warning] 21-21: wrong indentation: expected 2 but found 4

(indentation)


[warning] 30-30: wrong indentation: expected 2 but found 4

(indentation)


[warning] 38-38: wrong indentation: expected 2 but found 4

(indentation)


[warning] 41-41: wrong indentation: expected 2 but found 4

(indentation)


[warning] 54-54: wrong indentation: expected 0 but found 2

(indentation)

🧰 Additional context used
🧠 Learnings (1)
packages/extra/seaweedfs/templates/external-clients/deploy.yaml (1)

Learnt from: lllamnyp
PR: #1160
File: packages/system/hetzner-robotlb/charts/robotlb/templates/role.yaml:6-8
Timestamp: 2025-07-11T06:28:13.696Z
Learning: In Helm templates, the {{- directive chomps all leading whitespace including newlines back to the previous content, so {{- toYaml .Values.something | nindent 2 }} will render correctly even with apparent indentation issues. However, for better style, it's cleaner to put the template directive on the same line as the parent key (e.g., rules: {{- toYaml .Values.serviceAccount.permissions | nindent 2 }}).

🪛 YAMLlint (1.37.1)
packages/extra/seaweedfs/templates/external-clients/deploy.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/extra/seaweedfs/templates/external/cosi-cluster-role.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)


[warning] 21-21: wrong indentation: expected 2 but found 4

(indentation)


[warning] 30-30: wrong indentation: expected 2 but found 4

(indentation)


[warning] 38-38: wrong indentation: expected 2 but found 4

(indentation)


[warning] 41-41: wrong indentation: expected 2 but found 4

(indentation)


[warning] 54-54: wrong indentation: expected 0 but found 2

(indentation)

namespace: {{ $.Release.namespace }}
labels:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

.Release.namespace is undefined – results in empty namespace: fields

Helm’s Release object uses the capitalised key Namespace.
Using the lowercase variant renders an empty string, causing the Deployment and Secret to be created in the default namespace.

-  namespace: {{ $.Release.namespace }}
+  namespace: {{ $.Release.Namespace }}
...
-  namespace: {{ $.Release.namespace }}
+  namespace: {{ $.Release.Namespace }}

Also applies to: 135-136

🤖 Prompt for AI Agents
In packages/extra/seaweedfs/templates/external-clients/deploy.yaml at lines
10-11 and 135-136, the namespace field uses the incorrect lowercase key
`.Release.namespace`, which is undefined and results in an empty namespace
value. Change `.Release.namespace` to `.Release.Namespace` with a capital 'N' to
correctly reference the Helm Release object's Namespace property and ensure
resources are created in the intended namespace.

Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
@kvaps Andrei Kvapil (kvaps) changed the title seaweedfs external [seaweedfs] Add External topology Jul 23, 2025

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (4)
packages/extra/seaweedfs/values.yaml (1)

35-54: Example block leaks a full JWT & fails linters – replace with a placeholder

Keeping a real-looking token in the repo triggers secret-scanners (see Gitleaks) and the trailing blanks on several comment lines break yamllint.
Sanitise the example and strip whitespace.

 ##     token: "eyJhbGciOiJSUzI1NiIsImtpZCI6IlJMaEMyMTVvdDVVSENqZ1EySEFtVUhobnp2Mi02RXJ4bWM0bDJVenJmYzgifQ...
+##     # token: "<REDACTED>"

Afterwards run make lint – it should go green.

packages/extra/seaweedfs/templates/external-clients/deploy.yaml (3)

1-3: Guard against nil lookup to prevent template panic

Same nil-deref risk as noted elsewhere. Wrap the annotation extraction in a check (see previous diff).


107-108: socket volume lacks a source – manifest rejected by API server

Add an emptyDir definition.

 - name: socket
+  emptyDir: {}

90-106: Deployment runs with default ServiceAccount – RBAC will break

serviceAccountName is missing; the driver & sidecar inherit the default SA in the remote namespace, which has no perms.

 spec:
+  serviceAccountName: {{ $.Release.Name }}-objectstorage-provisioner
   containers:
🧹 Nitpick comments (1)
packages/extra/seaweedfs/values.yaml (1)

6-9: Consider reflecting the new External mode in the default / docs

topology now supports External, yet the default and surrounding docs still emphasise Simple.
If External is expected to be the common path, update the default and/or add a note explaining when to use each mode.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 97fa149 and 42a70bc.

📒 Files selected for processing (6)
  • packages/extra/seaweedfs/README.md (1 hunks)
  • packages/extra/seaweedfs/templates/dashboard-resourcemap.yaml (3 hunks)
  • packages/extra/seaweedfs/templates/external-clients/deploy.yaml (1 hunks)
  • packages/extra/seaweedfs/templates/external/cosi-deployment.yaml (1 hunks)
  • packages/extra/seaweedfs/values.schema.json (2 hunks)
  • packages/extra/seaweedfs/values.yaml (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/extra/seaweedfs/README.md
  • packages/extra/seaweedfs/values.schema.json
  • packages/extra/seaweedfs/templates/dashboard-resourcemap.yaml
🧰 Additional context used
🧠 Learnings (2)
packages/extra/seaweedfs/templates/external-clients/deploy.yaml (1)

Learnt from: lllamnyp
PR: #1160
File: packages/system/hetzner-robotlb/charts/robotlb/templates/role.yaml:6-8
Timestamp: 2025-07-11T06:28:13.696Z
Learning: In Helm templates, the {{- directive chomps all leading whitespace including newlines back to the previous content, so {{- toYaml .Values.something | nindent 2 }} will render correctly even with apparent indentation issues. However, for better style, it's cleaner to put the template directive on the same line as the parent key (e.g., rules: {{- toYaml .Values.serviceAccount.permissions | nindent 2 }}).

packages/extra/seaweedfs/values.yaml (2)

Learnt from: lllamnyp
PR: #1160
File: packages/system/hetzner-robotlb/charts/robotlb/templates/role.yaml:6-8
Timestamp: 2025-07-11T06:28:13.696Z
Learning: In Helm templates, the {{- directive chomps all leading whitespace including newlines back to the previous content, so {{- toYaml .Values.something | nindent 2 }} will render correctly even with apparent indentation issues. However, for better style, it's cleaner to put the template directive on the same line as the parent key (e.g., rules: {{- toYaml .Values.serviceAccount.permissions | nindent 2 }}).

Learnt from: NickVolynkin
PR: #1120
File: packages/apps/ferretdb/README.md:35-37
Timestamp: 2025-07-02T09:58:11.406Z
Learning: In the cozystack repository, the maintainer NickVolynkin prefers to keep realistic-looking example credentials in README documentation rather than using generic placeholders like <ACCESS_KEY>, even though they are just examples and not real secrets.

🪛 YAMLlint (1.37.1)
packages/extra/seaweedfs/templates/external/cosi-deployment.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/extra/seaweedfs/templates/external-clients/deploy.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/extra/seaweedfs/values.yaml

[error] 38-38: trailing spaces

(trailing-spaces)

🪛 Gitleaks (8.27.2)
packages/extra/seaweedfs/values.yaml

53-53: Uncovered a JSON Web Token, which may lead to unauthorized access to web applications and sensitive user data.

(jwt)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build
🔇 Additional comments (1)
packages/extra/seaweedfs/templates/external/cosi-deployment.yaml (1)

42-46: remoteEndpoint value may be undefined

ENDPOINT falls back gracefully, but SEAWEEDFS_FILER pulls from .Values.remoteEndpoint, which is not present in values.yaml.
Either add it to values.yaml (with docs/schema) or derive it from chart context to avoid an empty env var.

Comment on lines +40 to +44
value: {{ printf "%s.seaweedfs.objectstorage.k8s.io" $client.namespace }}
- name: ENDPOINT
value: https://{{ $.Values.host | default (printf "s3.%s" $host) }}
- name: SEAWEEDFS_FILER
value: seaweedfs-filer:18888

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

ENDPOINT may resolve to https://s3. when namespace annotation is absent

If $host is empty the resulting URL is invalid. Provide a sensible fallback (e.g., "s3.local" or the chart’s host value should be required).

🤖 Prompt for AI Agents
In packages/extra/seaweedfs/templates/external-clients/deploy.yaml around lines
40 to 44, the ENDPOINT environment variable may resolve to an invalid URL like
"https://s3." if the $host variable is empty. To fix this, update the default
fallback value in the printf function to a sensible string such as "s3.local" or
ensure the chart's host value is required and used as the fallback, preventing
an incomplete URL.

Comment on lines +1 to +5
{{- if eq .Values.topology "Client" }}
{{- $myNS := lookup "v1" "Namespace" "" .Release.Namespace }}
{{- $ingress := index $myNS.metadata.annotations "namespace.cozystack.io/ingress" }}
{{- $host := index $myNS.metadata.annotations "namespace.cozystack.io/host" }}
---

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Mismatch & nil-deref: Client vs External and unchecked lookup

  1. Condition uses "Client" but the chart introduces "External" – the template will never render.
  2. lookup may return nil; accessing .metadata.annotations then panics during helm template.
-{{- if eq .Values.topology "Client" }}
+{{- if eq .Values.topology "External" }}
 {{- $myNS := lookup "v1" "Namespace" "" .Release.Namespace }}
-{{- $ingress := index $myNS.metadata.annotations "namespace.cozystack.io/ingress" }}
-{{- $host := index $myNS.metadata.annotations "namespace.cozystack.io/host" }}
+{{- $ingress := "" }}
+{{- $host := "" }}
+{{- if $myNS }}
+  {{- $ingress = index $myNS.metadata.annotations "namespace.cozystack.io/ingress" | default "" }}
+  {{- $host    = index $myNS.metadata.annotations "namespace.cozystack.io/host"    | default "" }}
+{{- end }}
🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

🤖 Prompt for AI Agents
In packages/extra/seaweedfs/templates/external/cosi-deployment.yaml lines 1 to
5, the condition incorrectly checks for "Client" instead of "External" as
defined in the chart, causing the template not to render. Also, the lookup
result is not checked for nil before accessing metadata.annotations, which can
cause a panic during helm template rendering. Fix this by changing the condition
to check for "External" and add a nil check for the lookup result before
accessing its metadata and annotations.

@kvaps

Copy link
Copy Markdown
Member Author

Closed in favor #1239

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant