Skip to content

OSAC-3053: implement fulfillment gRPC client stub - #94

Merged
omer-vishlitzky merged 1 commit into
osac-project:mainfrom
rgolangh:feat/OSAC-3053-fulfillment-grpc-client
Aug 12, 2026
Merged

OSAC-3053: implement fulfillment gRPC client stub#94
omer-vishlitzky merged 1 commit into
osac-project:mainfrom
rgolangh:feat/OSAC-3053-fulfillment-grpc-client

Conversation

@rgolangh

@rgolangh rgolangh commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Summary

Wire the gRPC connection to the fulfillment-service in the CSI driver. When --fulfillment-endpoint is set, dialFulfillment() establishes a TLS connection with optional file-based bearer token auth. The connection is established but stubs are still used for VolumeClient and ControlPlaneClient until the Volume API is implemented server-side (OSAC-2872).

Only osac-csi-driver/ files changed. No operator, fulfillment-service, or other component changes.

What's added

  • --fulfillment-token-file and --grpc-insecure CLI flags
  • dialFulfillment() with TLS (ALPN-disabled for OpenShift router compat, MinVersion: tls.VersionTLS12), fileTokenSource for rotated token auth
  • Helm chart: controller.fulfillment.endpoint, controller.fulfillment.credentials.secretName/.key, controller.fulfillment.tls.insecureSkipVerify
  • Credentials Secret mounted at /etc/osac-csi/credentials/ — CSI driver runs on tenant clusters, AAP provisions the Secret

Test plan

  • go build ./osac-csi-driver/... — builds
  • helm lint — passes
  • helm template — all value combinations render correctly

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added configurable fulfillment service connectivity for the CSI driver.
    • Added bearer-token authentication using a Kubernetes Secret and token file.
    • Added optional TLS certificate verification settings.
    • Fulfillment credentials are mounted securely as read-only configuration.
    • Added support for authenticated gRPC connections to the configured fulfillment service.
  • Bug Fixes

    • The driver now establishes the configured fulfillment connection during startup and reports connection failures immediately.
    • Replaced the legacy fulfillment endpoint setting with the nested fulfillment configuration.

@openshift-ci-robot

openshift-ci-robot commented Aug 2, 2026

Copy link
Copy Markdown

@rgolangh: This pull request references OSAC-3053 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the task to target the "5.0.0" version, but no target version was set.

Details

In response to this:

Summary

  • Replace the CSI driver's LoggingStub with a real gRPC client (GRPCClient) that connects to the fulfillment-service's StorageTiers and StorageBackends APIs to resolve tier-to-backend routing info
  • Add buf.gen.yaml pointing at BSR module buf.build/osac-project/private-api:v0.0.79 to generate gRPC client stubs (same pattern as osac-operator)
  • Wire --fulfillment-token-file, --grpc-insecure, --grpc-plaintext CLI flags with file-based token auth (re-read on every call for rotation)
  • Update Helm chart controller deployment to mount a credentials Secret and pass the new flags — the CSI driver runs on tenant clusters where the hub SA token is not valid, so AAP must provision a Secret with a fulfillment-service bearer token

Test plan

  • 9 unit tests with in-process mock gRPC server (happy path, tier not found, backend not found, no vendor socket, no backend associations, list error, NFS protocol, close, protocol string conversion)
  • golangci-lint — 0 issues
  • helm lint — passes
  • Live integration test: Resolve("default", "gold") against kind-dev fulfillment-service returns Backend: vast, Endpoint: /csi/vast/csi.sock, Protocol: block
  • Helm deployment on kind-dev: controller pod starts, credentials Secret mounted at /etc/osac-csi/credentials/token, gRPC client connects to fulfillment-service

🤖 Generated with Claude Code

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

The controller configuration now defines fulfillment endpoint, credentials, and TLS settings. Helm conditionally mounts the credential Secret and passes connection arguments. The CSI driver establishes an authenticated TLS gRPC connection and retains in-memory stubs when no endpoint is configured.

Changes

Fulfillment connection configuration

Layer / File(s) Summary
Fulfillment configuration contract
osac-csi-driver/charts/csi-driver/values.yaml
Replaces controller.fulfillmentEndpoint with nested endpoint, credential Secret, token key, and TLS settings.
Credential and argument deployment wiring
osac-csi-driver/charts/csi-driver/templates/controller-deployment.yaml
Adds conditional fulfillment arguments, a read-only credential mount, and a Secret-backed volume.
Authenticated fulfillment connection
osac-csi-driver/cmd/osac-csi-driver/main.go, osac-csi-driver/go.mod
Adds TLS gRPC dialing, optional OAuth bearer-token credentials, token-file handling, connection cleanup, and related dependencies.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Helm
  participant ControllerDeployment
  participant CSIDriver
  participant FulfillmentEndpoint
  Helm->>ControllerDeployment: Render endpoint and credential settings
  ControllerDeployment->>CSIDriver: Pass fulfillment arguments and mount token file
  CSIDriver->>FulfillmentEndpoint: Establish authenticated TLS gRPC connection
  FulfillmentEndpoint-->>CSIDriver: Return connection or connection error
Loading

Possibly related PRs

  • osac-project/osac#75: Modifies the same fulfillment configuration, deployment template, driver startup, and dependency files.
  • osac-project/osac#141: Reworks the fulfillment client startup path and controller deployment endpoint configuration.
  • osac-project/osac#201: Adds the Volume API that the fulfillment connection can use.

Suggested labels: lgtm

Suggested reviewers: avishayt, eliorerz


Caution

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

  • Ignore

❌ Failed checks (2 errors, 1 warning)

Check name Status Explanation Resolution
Container-Privileges ❌ Error The chart defaults node.privileged to true; node DaemonSets render privileged containers and the main node container also sets runAsUser: 0. Set node.privileged to false and avoid runAsUser: 0 where possible; if CSI node access requires privilege, document and narrowly justify the exception.
No-Sensitive-Data-In-Logs ❌ Error main.go logs the configured fulfillment endpoint verbatim; the chart documents an internal service hostname, so logs expose internal hostnames and any embedded endpoint credentials. Remove the endpoint value from logs, or log only a redacted/sanitized host identifier. Do not include endpoint userinfo or credentials in connection errors.
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (8 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: implementing a fulfillment gRPC client stub.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
No-Hardcoded-Secrets ✅ Passed Changed lines contain no secret values, embedded credentials, private keys, or credential literals; they reference a Kubernetes Secret/token file, and go.sum entries are dependency checksums.
No-Weak-Crypto ✅ Passed The PR diff uses TLS 1.2 and OAuth bearer tokens, with no MD5, SHA1, DES, RC4, Blowfish, ECB, custom crypto, or secret comparisons.
No-Injection-Vectors ✅ Passed The commit adds no SQL construction, shell execution, eval/exec, pickle.loads, yaml.load, os.system, or dangerouslySetInnerHTML; inputs reach only grpc.NewClient and os.ReadFile.
Ai-Attribution ✅ Passed AI use is disclosed in the PR, and the change commit has an Assisted-by: Claude Code trailer; it has no AI Co-Authored-By trailer.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

Comment @coderabbitai help to get the list of available commands.

@rgolangh
rgolangh force-pushed the feat/OSAC-3053-fulfillment-grpc-client branch from 177f9ca to feb5645 Compare August 2, 2026 15:35
@rgolangh
rgolangh force-pushed the feat/OSAC-3053-fulfillment-grpc-client branch from 90f59e0 to 8a1ffbd Compare August 2, 2026 16:23
Comment thread osac-operator/buf.gen.yaml Outdated

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.

@rgolangh Now that the operator and fulfillment-service are in the same repo, should buf.gen.yaml generate from local proto directories (../fulfillment-service/proto/private) instead of pulling from BSR?

That would remove the version pinning and let proto changes flow through without a publish-then-pull cycle.

Not blocking, just wondering if that's planned as a follow-up.

cc: @omer-vishlitzky @eliorerz @eranco74

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.

active discussion, see here: https://redhat.atlassian.net/browse/OSAC-1735

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'll wait for this ticket to resolve, meanwhile this PR doesn't need a full blown client. This was a claude mistake

@akshaynadkarni akshaynadkarni 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.

Overall, changes LGTM.
Thanks for addressing my comments from the previous PR.

Please see my comment here before merging. Not sure if this something you'd like to tackle as part of this PR. It's a non-blocking comment.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@osac-csi-driver/charts/csi-driver/templates/controller-deployment.yaml`:
- Around line 29-38: Update the .Values.controller.fulfillment rendering block
so that when endpoint is set, both credentials.secretName and credentials.key
are validated as required and Helm rendering fails if either is empty; only
render --fulfillment-token-file after validation, while preserving the existing
endpoint and TLS flag behavior.

In `@osac-operator/pkg/fulfillment/conn.go`:
- Around line 48-50: Update the connection error returned by grpc.NewClient in
the fulfillment connection setup to omit the endpoint value and use a generic
descriptive message while preserving the wrapped underlying error. Keep the
existing successful connection flow unchanged.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: osac-project/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: f9d34545-90c0-4652-8627-54c2ba23fb9c

📥 Commits

Reviewing files that changed from the base of the PR and between e349d0b and 248c77d.

⛔ Files ignored due to path filters (1)
  • osac-csi-driver/go.sum is excluded by !**/*.sum
📒 Files selected for processing (8)
  • osac-csi-driver/Containerfile
  • osac-csi-driver/charts/csi-driver/templates/controller-deployment.yaml
  • osac-csi-driver/charts/csi-driver/values.yaml
  • osac-csi-driver/cmd/osac-csi-driver/main.go
  • osac-csi-driver/go.mod
  • osac-csi-driver/pkg/fulfillment/client.go
  • osac-operator/cmd/main.go
  • osac-operator/pkg/fulfillment/conn.go
🚧 Files skipped from review as they are similar to previous changes (5)
  • osac-csi-driver/cmd/osac-csi-driver/main.go
  • osac-csi-driver/go.mod
  • osac-csi-driver/pkg/fulfillment/client.go
  • osac-csi-driver/charts/csi-driver/values.yaml
  • osac-csi-driver/Containerfile

Comment on lines +29 to +38
{{- with .Values.controller.fulfillment }}
{{- if .endpoint }}
- "--fulfillment-endpoint={{ .endpoint }}"
{{- if .credentials.secretName }}
- "--fulfillment-token-file=/etc/osac-csi/credentials/{{ .credentials.key }}"
{{- end }}
{{- if .tls.insecureSkipVerify }}
- "--grpc-insecure"
{{- end }}
{{- end }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Fail the Helm render when the endpoint has no credentials.

The chart documents credentials.secretName as required when endpoint is set. This block still renders --fulfillment-endpoint without --fulfillment-token-file when the Secret name is empty. main.go then passes an empty token file, and osac-operator/pkg/fulfillment/conn.go omits bearer credentials. The deployment can start with a configured but unauthenticated client.

Validate credentials.secretName and credentials.key when endpoint is set. If unauthenticated endpoints are supported, update the chart contract instead.

Proposed validation
             {{- if .endpoint }}
+            {{- if not .credentials.secretName }}
+            {{- fail "controller.fulfillment.credentials.secretName is required when endpoint is set" }}
+            {{- end }}
+            {{- if not .credentials.key }}
+            {{- fail "controller.fulfillment.credentials.key is required when endpoint is set" }}
+            {{- end }}
             - "--fulfillment-endpoint={{ .endpoint }}"
-            {{- if .credentials.secretName }}
             - "--fulfillment-token-file=/etc/osac-csi/credentials/{{ .credentials.key }}"
-            {{- end }}
             {{- if .tls.insecureSkipVerify }}
📝 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
{{- with .Values.controller.fulfillment }}
{{- if .endpoint }}
- "--fulfillment-endpoint={{ .endpoint }}"
{{- if .credentials.secretName }}
- "--fulfillment-token-file=/etc/osac-csi/credentials/{{ .credentials.key }}"
{{- end }}
{{- if .tls.insecureSkipVerify }}
- "--grpc-insecure"
{{- end }}
{{- end }}
{{- with .Values.controller.fulfillment }}
{{- if .endpoint }}
{{- if not .credentials.secretName }}
{{- fail "controller.fulfillment.credentials.secretName is required when endpoint is set" }}
{{- end }}
{{- if not .credentials.key }}
{{- fail "controller.fulfillment.credentials.key is required when endpoint is set" }}
{{- end }}
- "--fulfillment-endpoint={{ .endpoint }}"
- "--fulfillment-token-file=/etc/osac-csi/credentials/{{ .credentials.key }}"
{{- if .tls.insecureSkipVerify }}
- "--grpc-insecure"
{{- end }}
{{- end }}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@osac-csi-driver/charts/csi-driver/templates/controller-deployment.yaml`
around lines 29 - 38, Update the .Values.controller.fulfillment rendering block
so that when endpoint is set, both credentials.secretName and credentials.key
are validated as required and Helm rendering fails if either is empty; only
render --fulfillment-token-file after validation, while preserving the existing
endpoint and TLS flag behavior.

Comment thread osac-operator/pkg/fulfillment/conn.go Outdated
Comment on lines +48 to +50
conn, err := grpc.NewClient(endpoint, dialOpts...)
if err != nil {
return nil, fmt.Errorf("connecting to fulfillment-service at %s: %w", endpoint, err)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

Do not include the endpoint in the returned error.

osac-operator/cmd/main.go logs this error. The configured endpoint can contain an internal hostname. Return a generic connection error instead.

Proposed fix
-	return nil, fmt.Errorf("connecting to fulfillment-service at %s: %w", endpoint, err)
+	return nil, fmt.Errorf("connecting to fulfillment-service: %w", err)
📝 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
conn, err := grpc.NewClient(endpoint, dialOpts...)
if err != nil {
return nil, fmt.Errorf("connecting to fulfillment-service at %s: %w", endpoint, err)
conn, err := grpc.NewClient(endpoint, dialOpts...)
if err != nil {
return nil, fmt.Errorf("connecting to fulfillment-service: %w", err)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@osac-operator/pkg/fulfillment/conn.go` around lines 48 - 50, Update the
connection error returned by grpc.NewClient in the fulfillment connection setup
to omit the endpoint value and use a generic descriptive message while
preserving the wrapped underlying error. Keep the existing successful connection
flow unchanged.

Source: Coding guidelines

@rgolangh
rgolangh force-pushed the feat/OSAC-3053-fulfillment-grpc-client branch from 248c77d to 9d535e3 Compare August 6, 2026 15:35
Comment thread osac-csi-driver/Containerfile Outdated
RUN cd osac-csi-driver && go mod download

COPY --chown=1001:1001 osac-csi-driver/ osac-csi-driver/
COPY --chown=1001:1001 osac-operator/pkg/ osac-operator/pkg/

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.

Is this still needed? The CSI driver no longer imports from osac-operator after the shared conn.go was dropped.

Comment thread osac-csi-driver/go.mod Outdated
gopkg.in/yaml.v2 v2.4.0 // indirect
)

replace github.com/osac-project/osac-operator => ../osac-operator

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.

Same question: is this replace still needed? No code imports from osac-operator now.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

no, this is all left overs, and will be removed in the following push

@akshaynadkarni akshaynadkarni 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.

Overall changes LGTM.
Left a couple of nits. PTAL.

@openshift-ci openshift-ci Bot added the lgtm label Aug 7, 2026
@openshift-ci

openshift-ci Bot commented Aug 7, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: akshaynadkarni, rgolangh

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@osac-csi-driver/cmd/osac-csi-driver/main.go`:
- Line 69: Update the fulfillment endpoint log in the startup flow to avoid
including the value of fulfillmentEndpoint. Keep a status message indicating
that fulfillment is configured and connected, but remove the endpoint
interpolation entirely.
- Line 107: Update the startup connection flow around grpc.NewClient to verify
connectivity before reporting successful initialization: when the endpoint is
non-empty, trigger or establish the ClientConn connection and wait with a
bounded context, propagating timeout or connection errors; only log successful
startup after this check completes.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: osac-project/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 0ff208fe-3b2e-4010-b264-823be35c3a4e

📥 Commits

Reviewing files that changed from the base of the PR and between 248c77d and 9b31d59.

📒 Files selected for processing (4)
  • osac-csi-driver/charts/csi-driver/templates/controller-deployment.yaml
  • osac-csi-driver/charts/csi-driver/values.yaml
  • osac-csi-driver/cmd/osac-csi-driver/main.go
  • osac-csi-driver/go.mod
🚧 Files skipped from review as they are similar to previous changes (2)
  • osac-csi-driver/charts/csi-driver/values.yaml
  • osac-csi-driver/charts/csi-driver/templates/controller-deployment.yaml

Comment thread osac-csi-driver/cmd/osac-csi-driver/main.go
Comment thread osac-csi-driver/cmd/osac-csi-driver/main.go
@akshaynadkarni

Copy link
Copy Markdown
Contributor

/lgtm /approve

@akshaynadkarni

Copy link
Copy Markdown
Contributor

/lgtm

1 similar comment
@akshaynadkarni

Copy link
Copy Markdown
Contributor

/lgtm

@rgolangh

Copy link
Copy Markdown
Contributor Author

/retest

@github-actions

Copy link
Copy Markdown

Re-triggered failed runs:

  • label-gate (#31388081710)
  • E2E VMaaS Full Install (#31388081825)

@rgolangh

Copy link
Copy Markdown
Contributor Author

/retest

@github-actions

Copy link
Copy Markdown

Re-triggered failed runs:

  • label-gate (#31388081710)

@omer-vishlitzky

Copy link
Copy Markdown
Contributor

/retest

@github-actions

Copy link
Copy Markdown

Re-triggered failed runs:

  • label-gate (#31388081710)
  • E2E VMaaS Full Install (#31388081825)

@akshaynadkarni

Copy link
Copy Markdown
Contributor

/retest

@github-actions

Copy link
Copy Markdown

Re-triggered failed runs:

  • E2E VMaaS Full Install (#31388081825)
  • label-gate (#31388081710)

Wire the gRPC connection to the fulfillment-service in the CSI driver.
When --fulfillment-endpoint is set, dialFulfillment() establishes a TLS
connection (ALPN-disabled for OpenShift router compat) with optional
file-based bearer token auth. The connection is established but stubs
are still used for VolumeClient and ControlPlaneClient until the Volume
API is implemented server-side (OSAC-2872).

- Add --fulfillment-token-file and --grpc-insecure CLI flags
- Add dialFulfillment() with TLS (MinVersion 1.2) and fileTokenSource
- Update Helm chart to mount a credentials Secret at
  /etc/osac-csi/credentials/ (CSI driver runs on tenant clusters
  where the hub SA token is not valid — AAP provisions the Secret)
- Gate --fulfillment-token-file on credentials.secretName

Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Roy Golan <rgolan@redhat.com>
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 11, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 8:36 PM UTC · Completed 8:57 PM UTC

Commit: 33c71d9 · View workflow run →

@omer-vishlitzky

Copy link
Copy Markdown
Contributor

/lgtm

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 11, 2026

Copy link
Copy Markdown

Review

Findings

High

  • [stale-doc] osac-csi-driver/README.md:38 — The Configuration table is missing the two new CLI flags (--fulfillment-token-file and --grpc-insecure). The description for --fulfillment-endpoint no longer reflects current behavior: setting it now establishes a gRPC connection rather than exiting with an error.
    Remediation: Add rows for the new flags and update the --fulfillment-endpoint description.

Medium

  • [scope-coherence] osac-csi-driver/AGENTS.md:110 — The Stub Mode section states "Setting --fulfillment-endpoint currently exits with an error" — now incorrect. The Configuration section also omits the new CLI flags and the restructured Helm values (controller.fulfillment.* replacing flat controller.fulfillmentEndpoint).
    Remediation: Update the Stub Mode and Configuration sections to describe current behavior.

  • [edge-case] osac-csi-driver/charts/csi-driver/templates/controller-deployment.yaml:50 — The volumeMounts/volumes conditionals access .Values.controller.fulfillment.credentials.secretName without nil guards. If a user explicitly sets credentials: null in their values override, the template will fail with a nil pointer dereference.
    Remediation: Add nil guards (e.g., {{- if and .credentials .credentials.secretName }}) or document that the nested structure must not be nulled.

Low

  • [logic-error] osac-csi-driver/cmd/osac-csi-driver/main.go:67 — Log says "connected" but grpc.NewClient is lazy — no TCP handshake occurs until the first RPC. Since stubs are used, the connection is never established.
  • [test-inadequate] osac-csi-driver/cmd/osac-csi-driver/main.go:89dialFulfillment and fileTokenSource have no unit tests.
  • [authentication-bypass] osac-csi-driver/cmd/osac-csi-driver/main.go:88 — No warning when --fulfillment-endpoint is set without --fulfillment-token-file.
  • [tls-verification-bypass] osac-csi-driver/charts/csi-driver/values.yaml:20 — No warning log when --grpc-insecure is active.
  • [fail-open-credentials] osac-csi-driver/charts/csi-driver/templates/controller-deployment.yaml:35 — If credentials.key mismatches the actual Secret key, mount succeeds but token file read fails at runtime.
  • [error-handling-gap] osac-csi-driver/cmd/osac-csi-driver/main.go:61conn from dialFulfillment is opened and deferred-closed but never used; stubs are always assigned (intentional per OSAC-2872).
  • [secrets-in-logs] osac-csi-driver/cmd/osac-csi-driver/main.go:66 — Bearer token held in memory as plain string; gRPC debug logging could expose it.
  • [architecture-coherence] osac-csi-driver/cmd/osac-csi-driver/main.go:75 — TLS setup diverges from metering-service by not supporting custom CA certificates.
  • [architecture-coherence] osac-csi-driver/cmd/osac-csi-driver/main.go:88fileTokenSource duplicates a pattern from fulfillment-service and metering-service.
  • [naming-convention] osac-csi-driver/charts/csi-driver/values.yaml — Nested controller.fulfillment introduces a second organizational pattern alongside flat controller.* keys.
  • [template-idiom-consistency] osac-csi-driver/charts/csi-driver/templates/controller-deployment.yaml:32{{- with }} scoping in args section is inconsistent with {{- if }} used elsewhere in this template.
  • [code-organization] osac-csi-driver/cmd/osac-csi-driver/main.go:89fileTokenSource has reuse potential and could live in pkg/.

Next steps:

  • /fs-fix — agent addresses review findings automatically
  • /fs-fix <your instruction> — agent fixes with your specific guidance
  • Push commits directly — review re-runs automatically on push
  • /fs-fix-stop — disable automatic fix runs for this PR

@fullsend-ai-review fullsend-ai-review Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

See the review comment for full details.

volumeMounts:
- name: osac-socket-dir
mountPath: /csi/osac
{{- if and .Values.controller.fulfillment.endpoint .Values.controller.fulfillment.credentials.secretName }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[medium] edge-case

The volumeMounts/volumes conditionals access .Values.controller.fulfillment.credentials.secretName without nil guards. If a user explicitly sets credentials: null in their values override, the template will fail with a nil pointer dereference.

Suggested fix: Add nil guards or document that the nested structure must not be nulled.

conn, err := dialFulfillment(*fulfillmentEndpoint, *grpcInsecure, *fulfillmentTokenFile)
if err != nil {
klog.Fatalf("Failed to connect to fulfillment-service: %v", err)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[low] logic-error

Log says 'connected' but grpc.NewClient is lazy -- no TCP handshake occurs until the first RPC. Since stubs are used, the connection is never established.

Suggested fix: Change log to say 'configured' instead of 'connected'.

}
}

func dialFulfillment(endpoint string, insecureSkipVerify bool, tokenFile string) (*grpc.ClientConn, error) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[low] test-inadequate

dialFulfillment and fileTokenSource have no unit tests. fileTokenSource.Token() is straightforward to test.

Suggested fix: Add unit tests for fileTokenSource.Token() covering valid token, missing file, empty file, trailing newlines.

@@ -72,6 +86,42 @@ func main() {
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[low] authentication-bypass

When --fulfillment-endpoint is set but --fulfillment-token-file is not provided, dialFulfillment() establishes a connection with TLS but no authentication credentials, with no warning.

Suggested fix: Add a log warning when token file is empty but endpoint is set.

# onto each tenant cluster during cluster setup.
fulfillment:
# gRPC endpoint of the fulfillment-service (e.g. "fulfillment-api.osac.svc:8000").
# Leave empty to use in-memory stubs.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[low] tls-verification-bypass

No warning log emitted when --grpc-insecure is active. Default is safe (false) and the flag name is self-documenting.

Suggested fix: Add a warning log when --grpc-insecure is true.

// and ControlPlaneClient once the Volume API is implemented.
conn, err := dialFulfillment(*fulfillmentEndpoint, *grpcInsecure, *fulfillmentTokenFile)
if err != nil {
klog.Fatalf("Failed to connect to fulfillment-service: %v", err)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[low] secrets-in-logs

Bearer token held in memory as plain string via fileTokenSource. If gRPC debug/trace logging is enabled, token metadata could be exposed in logs.

klog.Infof("No fulfillment endpoint configured, using in-memory stubs")
volumeClient = fulfillment.NewVolumeStub("default-backend", "nfs")
controlPlaneClient = &fulfillment.ControlPlaneStub{}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[low] architecture-coherence

TLS setup uses experimentalcredentials.NewTLSWithALPNDisabled (matching osac-operator) but diverges from metering-service by not supporting custom CA certificates.

@@ -72,6 +86,42 @@ func main() {
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[low] architecture-coherence

fileTokenSource duplicates a pattern from fulfillment-service (with modification-time caching) and metering-service. Could eventually be extracted to a shared package.

{{- end }}
{{- if .Values.controller.fulfillmentEndpoint }}
- "--fulfillment-endpoint={{ .Values.controller.fulfillmentEndpoint }}"
{{- with .Values.controller.fulfillment }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[low] template-idiom-consistency

with .Values.controller.fulfillment scoping in args section is inconsistent with if .Values.X used elsewhere. Volume conditionals use full paths without with.

Suggested fix: Use either with or full paths consistently for fulfillment-related conditionals.

}
}

func dialFulfillment(endpoint string, insecureSkipVerify bool, tokenFile string) (*grpc.ClientConn, error) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[low] code-organization

dialFulfillment and fileTokenSource in main.go is consistent with existing parseVendorSockets, but fileTokenSource has reuse potential and could live in pkg/.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants