Skip to content

Feat/rename ncx to nico#507

Open
shayan1995 wants to merge 1 commit intomainfrom
feat/rename-ncx-to-nico
Open

Feat/rename ncx to nico#507
shayan1995 wants to merge 1 commit intomainfrom
feat/rename-ncx-to-nico

Conversation

@shayan1995
Copy link
Copy Markdown
Contributor

Description

Type of Change

  • Feature - New feature or functionality (feat:)
  • Fix - Bug fixes (fix:)
  • Chore - Modification or removal of existing functionality (chore:)
  • Refactor - Refactoring of existing functionality (refactor:)
  • Docs - Changes in documentation or OpenAPI schema (docs:)
  • CI - Changes in GitHub workflows. Requires additional scrutiny (ci:)
  • Version - Issuing a new release version (version:)

Services Affected

  • API - API models or endpoints updated
  • Workflow - Workflow service updated
  • DB - DB DAOs or migrations updated
  • Site Manager - Site Manager updated
  • Cert Manager - Cert Manager updated
  • Site Agent - Site Agent updated
  • RLA - RLA service updated
  • Powershelf Manager - Powershelf Manager updated
  • NVSwitch Manager - NVSwitch Manager updated

Related Issues (Optional)

Breaking Changes

  • This PR contains breaking changes

Testing

  • Unit tests added/updated
  • Integration tests added/updated
  • Manual testing performed
  • No testing required (docs, internal refactor, etc.)

Additional Notes

@shayan1995 shayan1995 requested a review from a team as a code owner May 8, 2026 20:11
@copy-pr-bot
Copy link
Copy Markdown

copy-pr-bot Bot commented May 8, 2026

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 8, 2026

Summary by CodeRabbit

  • New Features & Updates
    • Migrated system branding and naming throughout the platform
    • Updated REST API endpoints from /carbide/ to /nico/ paths
    • Renamed command-line tool from carbidecli to nicocli
    • Updated configuration file paths and environment variables to use NICO_* naming
    • Refreshed authorization role constants for consistency
    • Updated database credentials and identifiers from legacy naming conventions
    • Renamed Docker images and Kubernetes resources to reflect new branding
    • Updated Helm charts for deployment and configuration management

Walkthrough

This pull request effectuates a complete conversion of the codebase, build/test/deploy infrastructure, configuration, and user/documentation surface from "Carbide" to "NICo". New canonical unprefixed role constants are introduced and used throughout all authorization, RBAC, and role-based checks. Every endpoint, YAML manifest, Helm chart, Docker image, test/fixture, and CLI/SDK component is updated for NICo branding and correctness. Handler/test logic generalize error and role matching for uniformity and future migration safety.

Changes

NICo Rebranding and Canonical Authorization Refactor

Layer / File(s) Summary
Canonical Roles, Shared RBAC Constants, and Matching Logic
common/pkg/roles/roles.go, all RBAC/config/authz Go files (auth/pkg/authorization/org.go, auth/pkg/config/roles.go, etc.)
Introduces central role constants (ProviderAdminRole, ProviderViewerRole, TenantAdminRole) and refactors all config, validation, and matching. Adds logic for robust, canonical, and dual-form (prefixed/unprefixed) role validation.
Build, CI/CD, Deployment Manifests, Helm/K8s, and Env Renaming
.github/, Makefile, deploy/*, docker/*, helm/*
Systematic, lossless migration of every build, artifact, image, manifest, namespace, and secret/config asset from Carbide to NICo—ensuring pipelines, labels, artifact keys, and environment variables are correct and future-proof.
User, Config, Documentation, and Default Value Branding
*.md, config files, YAML, comments, CLI help
Updates all project documentation (README, INSTALLATION, AGENTS, etc.), config defaults/paths, reference comments, and user-facing output to NICo conventions (including binary/config directories, CLI branding, and field-level comments).
REST Route, API Doc/Swagger Refactor
All API handler Go files, OpenAPI/Swagger/comments, and REST endpoint tests
Every API handler, doc comment, and test fixture is switched from the /carbide/... to /nico/... namespace. Swaps all test/fixture expectations to follow the new canonical path and doc structure, ensuring a single-brand REST API.
Generalized Handler Error/Role Assertion and Test Alignment
Handler error/role assertion logic, all unit/integration tests
Handler and tests are unified: role checks and skippable error detection employ canonical cross-form helpers and slices for robustness. All fixture/test/CLI role usage references explicit exported constants.
Test Artifacts, CLI, SDK, and Remaining User-Facing Conversion
CLI/TUI, SDK, config paths, all test data
All test fixtures, init flows, CLI commands/docs, environment variable names, and config directory logic are rewritten to use NICo identities, removing all Carbide tokens from the codebase and onboarding materials.

Sequence Diagram(s)

Not present—this refactor/unification targets structural, config, and naming layers globally and does not introduce new orchestrated flows between three or more runtime actors.

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/rename-ncx-to-nico
⚔️ Resolve merge conflicts
  • Resolve merge conflict in branch feat/rename-ncx-to-nico

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 8, 2026

Test Results

9 289 tests  ±0   9 289 ✅ ±0   6m 47s ⏱️ -34s
  154 suites ±0       0 💤 ±0 
   14 files   ±0       0 ❌ ±0 

Results for commit 6c297ee. ± Comparison against base commit 5cfe1d9.

♻️ This comment has been updated with latest results.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 18

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (10)
ipam/bun_test.go (1)

41-47: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

TestDBConfig.Name rename is not propagated to test connections.

Line 45 sets Name to nicotest, but the connection helpers still hardcode "postgres" (Line 82, Line 87, Line 92), so this rename is effectively bypassed in this file.

🔧 Proposed fix
 func getTestBundbSession(t *testing.T) (*bun.DB, error) {
 	cfg := getTestDBParams()
-	return newBunPostgres(cfg.Host, cfg.Port, cfg.User, cfg.Password, "postgres")
+	return newBunPostgres(cfg.Host, cfg.Port, cfg.User, cfg.Password, cfg.Name)
 }
 
 func getTestSqlxSession(t *testing.T) (sqlIf, error) {
 	cfg := getTestDBParams()
-	return newPostgres(cfg.Host, cfg.Port, cfg.User, cfg.Password, "postgres", SSLModeDisable)
+	return newPostgres(cfg.Host, cfg.Port, cfg.User, cfg.Password, cfg.Name, SSLModeDisable)
 }
 
 func getTestBadBundbSession(t *testing.T) (*bun.DB, error) {
 	cfg := getTestDBParams()
-	return newBunPostgres("1.2.3.4", cfg.Port, cfg.User, cfg.Password, "postgres")
+	return newBunPostgres("1.2.3.4", cfg.Port, cfg.User, cfg.Password, cfg.Name)
 }
🤖 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 `@ipam/bun_test.go` around lines 41 - 47, The TestDBConfig value sets Name to
"nicotest" in getTestDBParams but the test connection helpers in this file still
hardcode "postgres", so update those helpers to use the TestDBConfig.Name field
instead of the literal "postgres"; locate the connection-building functions in
this file (the helpers that create DB connection strings) and replace the
hardcoded database name with the passed-in cfg.Name/TestDBConfig.Name when
constructing the DSN or sql.Open calls.
api/pkg/api/handler/interface.go (1)

72-80: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Correct the Swagger path parameter name to match the route placeholder.

The @Param annotation uses instanceId (camelCase), but the corresponding @Router placeholder is instance_id (snake_case). This inconsistency will cause the generated OpenAPI documentation to desynchronize with the actual route definition.

Proposed fix
-// `@Param` instanceId path string true "ID of Instance"
+// `@Param` instance_id path string true "ID of Instance"
 // `@Param` status query string false "Filter by status" e.g. 'Pending', 'Error'"
 // `@Param` includeRelation query string false "Related entities to include in response e.g. 'Instance', 'Subnet'"
 // `@Param` pageNumber query integer false "Page number of results returned"
 // `@Param` pageSize query integer false "Number of results per page"
 // `@Param` orderBy query string false "Order by field"
 // `@Success` 200 {object} model.APIInterface
 // `@Router` /v2/org/{org}/nico/instance/{instance_id}/interface [get]
🤖 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 `@api/pkg/api/handler/interface.go` around lines 72 - 80, Update the Swagger
`@Param` for the path parameter in GetAllInterfaceHandler.Handle so the parameter
name matches the route placeholder: change the path param identifier from
instanceId to instance_id in the `@Param` annotation used for the instance ID;
ensure the edited annotation exactly matches the `@Router` placeholder
{instance_id} to keep generated OpenAPI docs in sync with the route.
api/pkg/api/handler/infinibandinterface.go (1)

73-82: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Correct Swagger path parameter declarations to match route templates.

The annotation blocks contain misaligned path parameters: Block 1 declares instanceId (camelCase) but the route template uses {instance_id} (snake_case); Block 2 declares instanceId and infinibandPartitionId as path parameters despite the route containing no such placeholders. These inconsistencies produce incorrect OpenAPI documentation.

Proposed annotation fixes
-// `@Param` instanceId path string true "ID of Instance"
+// `@Param` instance_id path string true "ID of Instance"
 // `@Param` status query string false "Filter by status" e.g. 'Pending', 'Error'"
 // `@Param` includeRelation query string false "Related entities to include in response e.g. 'Instance', 'Subnet'"
 // `@Param` pageNumber query integer false "Page number of results returned"
 // `@Param` pageSize query integer false "Number of results per page"
 // `@Param` orderBy query string false "Order by field"
 // `@Success` 200 {object} model.APIInterface
 // `@Router` /v2/org/{org}/nico/instance/{instance_id}/interface [get]

For lines 128–137, remove the spurious path declarations:

 // `@Param` org path string true "Name of NGC organization"
 // `@Param` siteId query string true "ID of Site"
-// `@Param` instanceId path string true "ID of Instance"
-// `@Param` infinibandPartitionId path string true "ID of InfiniBandPartition"
 // `@Param` status query string false "Filter by status" e.g. 'Pending', 'Error'"
 // `@Param` includeRelation query string false "Related entities to include in response e.g. 'InfiniBandPartition, Instance'"
 // `@Param` pageNumber query integer false "Page number of results returned"
 // `@Param` pageSize query integer false "Number of results per page"
 // `@Param` orderBy query string false "Order by field"
 // `@Success` 200 {object} model.APIInfiniBandInterface
 // `@Router` /v2/org/{org}/nico/infiniband-interface [get]
🤖 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 `@api/pkg/api/handler/infinibandinterface.go` around lines 73 - 82, The Swagger
annotations for GetAllInstanceInfiniBandInterfaceHandler.Handle contain
incorrect path parameter names and extraneous path params; update the comment
block above Handle so path parameters exactly match the route template (use
instance_id not instanceId) and remove any path declarations that are not
present in the route (e.g., infinibandPartitionId and any other spurious path
params); ensure `@Param` lines reflect only actual path placeholders and correct
casing to produce accurate OpenAPI docs.
cli/pkg/app.go (1)

52-98: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Restore legacy CARBIDE_* env-var fallbacks for CLI flags.

Lines 52–98 only register NICO_* env vars. This can break existing scripts that still export legacy names. Keep both during transition and prefer NICO_* first.

🔧 Proposed compatibility patch
 			&cli.StringFlag{
 				Name:    "config",
 				Usage:   "Path to config file",
-				EnvVars: []string{"NICO_CONFIG"},
+				EnvVars: []string{"NICO_CONFIG", "CARBIDE_CONFIG"},
 			},
 			&cli.StringFlag{
 				Name:    "base-url",
 				Usage:   "API base URL",
-				EnvVars: []string{"NICO_BASE_URL"},
+				EnvVars: []string{"NICO_BASE_URL", "CARBIDE_BASE_URL"},
 				Value:   defaultBaseURL,
 			},
 			&cli.StringFlag{
 				Name:    "org",
 				Usage:   "Organization name",
-				EnvVars: []string{"NICO_ORG"},
+				EnvVars: []string{"NICO_ORG", "CARBIDE_ORG"},
 			},
 			&cli.StringFlag{
 				Name:    "token",
 				Usage:   "API bearer token",
-				EnvVars: []string{"NICO_TOKEN"},
+				EnvVars: []string{"NICO_TOKEN", "CARBIDE_TOKEN"},
 			},
@@
 			&cli.StringFlag{
 				Name:    "token-url",
 				Usage:   "OIDC token endpoint URL for login and token refresh",
-				EnvVars: []string{"NICO_TOKEN_URL"},
+				EnvVars: []string{"NICO_TOKEN_URL", "CARBIDE_TOKEN_URL"},
 			},
 			&cli.StringFlag{
 				Name:    "keycloak-url",
 				Usage:   "Keycloak base URL (constructs token-url if --token-url is not set)",
-				EnvVars: []string{"NICO_KEYCLOAK_URL"},
+				EnvVars: []string{"NICO_KEYCLOAK_URL", "CARBIDE_KEYCLOAK_URL"},
 			},
 			&cli.StringFlag{
 				Name:    "keycloak-realm",
 				Usage:   "Keycloak realm (used with --keycloak-url)",
-				EnvVars: []string{"NICO_KEYCLOAK_REALM"},
+				EnvVars: []string{"NICO_KEYCLOAK_REALM", "CARBIDE_KEYCLOAK_REALM"},
 				Value:   "nico-dev",
 			},
 			&cli.StringFlag{
 				Name:    "client-id",
 				Usage:   "OAuth client ID",
-				EnvVars: []string{"NICO_CLIENT_ID"},
+				EnvVars: []string{"NICO_CLIENT_ID", "CARBIDE_CLIENT_ID"},
 				Value:   "nico-api",
 			},
🤖 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 `@cli/pkg/app.go` around lines 52 - 98, The CLI flags currently only use NICO_*
environment variable names (e.g., flags with EnvVars: []string{"NICO_CONFIG"},
"NICO_BASE_URL", "NICO_ORG", "NICO_TOKEN", "NICO_TOKEN_URL",
"NICO_KEYCLOAK_URL", "NICO_KEYCLOAK_REALM", "NICO_CLIENT_ID"); restore
backward-compatible CARBIDE_* fallbacks by updating each flag's EnvVars slice to
include both names with the NICO_* name first (for example EnvVars:
[]string{"NICO_CONFIG", "CARBIDE_CONFIG"}) so existing scripts still work while
preferring the new NICO variables; do this for all the flags that currently
reference only NICO_* (leave flags that had no env var like token-command/debug
unchanged) and keep existing Value/default settings.
api/pkg/api/handler/fabric.go (1)

67-74: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix Swagger siteId parameter annotations to match the path routes.

Line 73 and Line 235 routes require {siteId} in the path, but docs are inconsistent: GetAll omits it and Get marks it as query on Line 232. This causes inaccurate OpenAPI output.

📝 Suggested annotation correction
 // `@Param` org path string true "Name of NGC organization"
+// `@Param` siteId path string true "ID of Site"
 // `@Param` includeRelation query string false "Related entities to include in response e.g. 'InfrastructureProvider', 'Site'"
@@
-// `@Param` siteId query string true "ID of Site"
+// `@Param` siteId path string true "ID of Site"

Also applies to: 230-235

🤖 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 `@api/pkg/api/handler/fabric.go` around lines 67 - 74, The Swagger annotations
for the Fabric handlers are missing/incorrect for the siteId path parameter;
update the doc comments for GetAllFabricHandler.Handle (and the corresponding
Get handler) so that `@Param` siteId is declared as a path parameter (e.g. `@Param`
siteId path string true "Site ID") rather than omitted or marked as query, and
ensure the `@Router` paths include {siteId} to match the actual route signatures;
locate the comment blocks above the Handle methods in fabric.go and replace the
incorrect `@Param` for siteId (and any misplaced query annotation) with the
correct path declaration.
helm/charts/nico-rest/charts/nico-rest-cert-manager/values.yaml (1)

19-20: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Inconsistent image name still references "carbide".

The image.name value remains carbide-rest-cert-manager while other identifiers in this chart have been renamed to use nico-rest-cert-manager. This inconsistency may cause confusion or deployment failures if the container image registry is also being updated.

Proposed fix
 image:
-  name: carbide-rest-cert-manager
+  name: nico-rest-cert-manager
🤖 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 `@helm/charts/nico-rest/charts/nico-rest-cert-manager/values.yaml` around lines
19 - 20, The image.name value is inconsistent and should be updated from
"carbide-rest-cert-manager" to "nico-rest-cert-manager"; edit the values.yaml
entry for image.name to use "nico-rest-cert-manager" and then search the chart
for any remaining "carbide-rest-cert-manager" references (templates, Chart.yaml,
other values keys) to ensure all identifiers and image references are renamed
consistently.
api/pkg/api/handler/expectedmachine_test.go (1)

1902-1917: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Migrate the remaining regression tests to canonical NICo route/role inputs.

Line 1902 and Line 1995 still hit /carbide/..., and Line 1916 and Line 2010 still use hardcoded FORGE_PROVIDER_ADMIN. These two tests now validate legacy compatibility rather than the primary NICo surface, so NICo-specific regressions could slip through.

Proposed patch
-	req := httptest.NewRequest(http.MethodPost, "/v2/org/"+org+"/carbide/expected-machine", bytes.NewReader(reqBody))
+	req := httptest.NewRequest(http.MethodPost, "/v2/org/"+org+"/nico/expected-machine", bytes.NewReader(reqBody))
@@
-				Roles:       []string{"FORGE_PROVIDER_ADMIN"},
+				Roles:       []string{authz.ProviderAdminRole},
@@
-	url := "/v2/org/" + org + "/carbide/expected-machine/" + testEM.ID.String()
+	url := "/v2/org/" + org + "/nico/expected-machine/" + testEM.ID.String()
@@
-				Roles:       []string{"FORGE_PROVIDER_ADMIN"},
+				Roles:       []string{authz.ProviderAdminRole},

Also applies to: 1995-2011

🤖 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 `@api/pkg/api/handler/expectedmachine_test.go` around lines 1902 - 1917, Update
the test to use the canonical NICo route and role inputs instead of the legacy
carbide/ and FORGE_PROVIDER_ADMIN values: change the request path created in req
(currently "/v2/org/"+org+"/carbide/expected-machine") to the NICo path
"/v2/org/"+org+"/nico/expected-machine", and replace the hardcoded role in the
c.Set("user", &cdbm.User{... Roles: []string{"FORGE_PROVIDER_ADMIN"}, ...})
block with the NICo role (use the project canonical NICo role constant if
available, otherwise "NICO_PROVIDER_ADMIN") so the test validates the primary
NICo surface rather than legacy compatibility.
auth/pkg/authentication/keycloak_test.go (1)

1809-1823: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Remove the unreachable duplicate token-endpoint case.

Lines 1810 and 1819 contain identical predicates in the same switch statement. The first case matches and executes, rendering the second case unreachable dead code. The token-exchange error path in the mock server is never exercised.

Suggested fix
 		switch {
 		case strings.Contains(req.URL.Path, "/realms/nico/protocol/openid-connect/token"):
 			// Always return unauthorized for admin login
 			res.WriteHeader(http.StatusUnauthorized)
 			res.Write([]byte(`{"error":"invalid_grant","error_description":"Invalid credentials"}`))
 		case strings.Contains(req.URL.Path, "/admin/realms/nico/identity-provider/instances"):
 			// Return empty IDP list
 			res.WriteHeader(http.StatusOK)
 			res.Header().Set("Content-Type", "application/json")
 			res.Write([]byte(`[]`))
-		case strings.Contains(req.URL.Path, "/realms/nico/protocol/openid-connect/token"):
-			// Return error for token exchange
-			res.WriteHeader(http.StatusBadRequest)
-			res.Write([]byte(`{"error":"invalid_grant","error_description":"Authorization code expired"}`))
 		default:
 			res.WriteHeader(http.StatusNotFound)
 		}
🤖 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 `@auth/pkg/authentication/keycloak_test.go` around lines 1809 - 1823, The
switch in the test HTTP handler in keycloak_test.go has two identical cases
using strings.Contains(req.URL.Path,
"/realms/nico/protocol/openid-connect/token"), making the second (token-exchange
error) branch unreachable; remove the duplicate predicate and ensure there are
distinct predicates so admin login returns 401 while the token-exchange path
returns 400. Locate the handler switch (the cases using
strings.Contains(req.URL.Path, "/realms/nico/protocol/openid-connect/token") and
the token-exchange error branch) and either remove/merge the redundant case or
change the second case's predicate to the actual token-exchange endpoint used by
the code under test so the token-exchange error path is exercised.
deploy/kustomize/base/site-agent/rbac.yaml (1)

31-34: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Restrict secret permissions to explicitly required resources for least-privilege compliance.

The Role grants access to all secrets in the namespace. The site-agent statefulset references only three specific secrets (site-registration, core-grpc-client-site-agent-certs, temporal-client-site-agent-certs), making the current broad permission unnecessary. Apply resourceNames to limit access to only these required secrets:

rules:
  - apiGroups: [""]
    resources: ["secrets"]
    resourceNames: ["site-registration", "core-grpc-client-site-agent-certs", "temporal-client-site-agent-certs"]
    verbs: ["get", "list", "watch", "update", "patch"]
  - apiGroups: ["cert-manager.io"]
    resources: ["certificaterequests"]
    verbs: ["get", "list", "watch", "update", "patch"]

Splitting the rules allows certificaterequests to remain unrestricted (cert-manager creates these dynamically), while core secret access is scoped to known resources.

🤖 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 `@deploy/kustomize/base/site-agent/rbac.yaml` around lines 31 - 34, The Role
rule currently grants namespace-wide secret access; split the combined rule into
two rules: one for secrets that adds resourceNames limiting access to only the
three secrets referenced by the site-agent (site-registration,
core-grpc-client-site-agent-certs, temporal-client-site-agent-certs) and a
separate rule for cert-manager.io certificaterequests (leave certificaterequests
unrestricted), ensuring you update the rules block to reference resources
["secrets"] with resourceNames set to those three names and resources
["certificaterequests"] under apiGroups ["cert-manager.io"] for the other rule.
deploy/INSTALLATION.md (1)

899-906: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Align the token example with the documented seeded admin user.

This guide lists the pre-seeded admin username as admin, but the curl example authenticates as admin@example.com. That inconsistency is enough to block first-time setup unless email login is explicitly enabled and documented here.

As per coding guidelines, **/*.md: "Assess the documentation for misspellings, grammatical errors, missing documentation and correctness".

🤖 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 `@deploy/INSTALLATION.md` around lines 899 - 906, The token curl example uses
username=admin@example.com which conflicts with the documented seeded admin user
"admin"; update the TOKEN acquisition snippet (the curl POST that sets TOKEN and
uses client_id=nico-api and realm nico-dev) to use username=admin (or clearly
document that email login must be enabled) so the example matches the seeded
admin credentials in the guide.
🟡 Minor comments (15)
api/pkg/api/handler/machinevalidation.go-697-697 (1)

697-697: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Align router path placeholder names with handler parameter keys.

Lines 697/833/1098/1386/1594 use {id} or {name}, while handlers read machineID / cfgName from c.Param(...). Keep these names consistent to prevent ambiguous or incorrect generated API docs.

Proposed fix
-// `@Router` /v2/org/{org}/nico/site/{site}/machine-validation/results/machine/{id} [get]
+// `@Router` /v2/org/{org}/nico/site/{site}/machine-validation/results/machine/{machineID} [get]

-// `@Router` /v2/org/{org}/nico/site/{site}/machine-validation/runs/machine/{id} [get]
+// `@Router` /v2/org/{org}/nico/site/{site}/machine-validation/runs/machine/{machineID} [get]

-// `@Router` /v2/org/{org}/nico/site/{site}/machine-validation/external-config/{name} [get]
+// `@Router` /v2/org/{org}/nico/site/{site}/machine-validation/external-config/{cfgName} [get]

-// `@Router` /v2/org/{org}/nico/site/{site}/machine-validation/external-config/{name} [patch]
+// `@Router` /v2/org/{org}/nico/site/{site}/machine-validation/external-config/{cfgName} [patch]

-// `@Router` /v2/org/{org}/nico/site/{site}/machine-validation/external-config/{name} [delete]
+// `@Router` /v2/org/{org}/nico/site/{site}/machine-validation/external-config/{cfgName} [delete]

Also applies to: 833-833, 1098-1098, 1386-1386, 1594-1594

🤖 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 `@api/pkg/api/handler/machinevalidation.go` at line 697, Route placeholder
names in the swagger route comments must match the handler parameter keys;
update each router comment that currently uses {id} or {name} to use {machineID}
or {cfgName} respectively so they match c.Param("machineID") and
c.Param("cfgName") used in the handlers (e.g., the comment above the handler
that reads c.Param("machineID") should use /machine/{machineID} and the one that
reads c.Param("cfgName") should use /{cfgName}); locate the affected router
comments near the functions that call c.Param("machineID") / c.Param("cfgName")
and replace the placeholder tokens accordingly to keep generated API docs
unambiguous.
api/pkg/api/handler/nvlinkinterface.go-81-81 (1)

81-81: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use consistent instance path parameter naming in router annotation.

Line 81 uses {instance_id} but the handler and @Param use instanceId. This inconsistency can degrade generated API docs/clients.

Proposed fix
-// `@Router` /v2/org/{org}/nico/instance/{instance_id}/interface [get]
+// `@Router` /v2/org/{org}/nico/instance/{instanceId}/interface [get]
🤖 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 `@api/pkg/api/handler/nvlinkinterface.go` at line 81, The router annotation
uses a different instance path parameter name ({instance_id}) than the
handler/@Param (instanceId); update the `@Router` annotation to use {instanceId}
so it matches the `@Param` and handler signature in nvlinkinterface.go (ensure the
route line with "/v2/org/{org}/nico/instance/{instanceId}/interface [get]"
matches the existing `@Param` instanceId and the handler function that expects
instanceId).
api/pkg/api/handler/site.go-1169-1169 (1)

1169-1169: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix path casing mismatch in status-history route annotation.

Line 1169 uses /nico/Site/{id}/... while the rest of this file uses lowercase site. This can produce an incorrect OpenAPI path for consumers.

Suggested fix
-// `@Router` /v2/org/{org}/nico/Site/{id}/status-history [get]
+// `@Router` /v2/org/{org}/nico/site/{id}/status-history [get]
🤖 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 `@api/pkg/api/handler/site.go` at line 1169, Update the Router annotation
string that currently reads "/v2/org/{org}/nico/Site/{id}/status-history" to use
lowercase "site" so it matches the rest of the file and generated OpenAPI paths;
i.e., change the annotation in site.go for the status-history route to
"/v2/org/{org}/nico/site/{id}/status-history" (the comment/annotation on the
status-history handler).
.github/scripts/promote-single-ngc-resource.sh-32-33 (1)

32-33: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Keep the promotion log aligned with DEST_TEAM.

Line 77 now reports an upload to nico, but Lines 78-79 still authenticate and push to DEST_TEAM, which remains carbide. That makes promotion logs misleading until the actual destination team changes.

Suggested fix
-    echo "Uploading to nico/$RESOURCE_NAME:$SEMANTIC_VERSION..."
+    echo "Uploading to ${DEST_TEAM}/$RESOURCE_NAME:$SEMANTIC_VERSION..."

Also applies to: 77-79

🤖 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 @.github/scripts/promote-single-ngc-resource.sh around lines 32 - 33, The
promotion log prints a hardcoded "nico" while the script uses the DEST_TEAM
variable ("carbide"), causing misleading messages; update the upload/promotion
log to reference the DEST_TEAM variable (use "${DEST_TEAM}" consistently)
instead of the literal "nico" and ensure the subsequent authentication/push
commands that already use DEST_TEAM remain in sync with that log message so all
output reflects the actual destination team.
cli/README.md-183-189 (1)

183-189: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add a language identifier to this fenced block.

This block is still unlabeled, so markdownlint MD040 will keep warning on the README. text is sufficient here.

🤖 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 `@cli/README.md` around lines 183 - 189, The README's fenced code block listing
config files is unlabeled causing markdownlint MD040; update the triple-backtick
fence that encloses the lines starting with "~/.nico/config.yaml" so it becomes
"```text" (i.e., add the language identifier "text" to the opening fence) to
satisfy the linter without changing the block content.
cli/README.md-147-147 (1)

147-147: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use nicocli in the command synopsis.

Line 147 is the only place still documenting the command as cli <resource> ..., which contradicts the install and usage sections and points readers at a nonexistent binary name.

As per coding guidelines "Assess the documentation for misspellings, grammatical errors, missing documentation and correctness".

🤖 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 `@cli/README.md` at line 147, Replace the incorrect command synopsis text "cli
<resource> [sub-resource] <action> [args] [flags]" in the README with the actual
binary name used elsewhere by the project: "nicocli <resource> [sub-resource]
<action> [args] [flags]"; update that single occurrence so the command synopsis
matches the install and usage sections and points to the real executable.
api/pkg/api/handler/vpc_test.go-2021-2021 (1)

2021-2021: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use the actual virtualization route template here.

Line 2021 still sets /v2/org/%v/nico/vpc/%v, but the handler is documented and routed as /v2/org/{org}/nico/vpc/{id}/virtualization. Keeping the Echo path aligned prevents this test from missing path-template-dependent behavior in middleware and tracing.

Suggested fix
-			ec.SetPath(fmt.Sprintf("/v2/org/%v/nico/vpc/%v", tt.args.reqOrg, tt.args.reqVPCID))
+			ec.SetPath(fmt.Sprintf("/v2/org/%v/nico/vpc/%v/virtualization", tt.args.reqOrg, tt.args.reqVPCID))
🤖 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 `@api/pkg/api/handler/vpc_test.go` at line 2021, The test currently sets the
Echo request path to "/v2/org/%v/nico/vpc/%v" which does not match the handler's
routed template; update the ec.SetPath call in vpc_test.go to use the full
virtualization route "/v2/org/%v/nico/vpc/%v/virtualization" (still formatting
with tt.args.reqOrg and tt.args.reqVPCID) so that middleware/tracing and
path-template-dependent behavior for the handler (referenced by ec.SetPath) are
exercised correctly.
auth/README.md-199-201 (1)

199-201: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Align Keycloak example values with the shipped kustomize defaults.

This guide tells users to edit the existing nico-rest-api-config, but the sample uses realm: nico / clientID: nico-cloud while the base manifest uses realm: nico-dev / clientID: nico-api. Please make the difference explicit (e.g., “production override”) or make values consistent to avoid broken copy/paste setups.

As per coding guidelines, **/*.md: "Assess the documentation for misspellings, grammatical errors, missing documentation and correctness".

Also applies to: 230-233

🤖 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 `@auth/README.md` around lines 199 - 201, Update the Keycloak example values in
the README so they match the shipped kustomize defaults or clearly mark them as
production overrides: change the sample for `keycloak.realm` and
`keycloak.clientID` to the base manifest values (`nico-dev` and `nico-api`) or
add an explicit note (e.g., “production override: realm=nico,
clientID=nico-cloud”) next to `keycloak.realm`, `keycloak.clientID`, and keep
`keycloak.clientSecretPath` as-is; ensure the same change is applied to the
other occurrence mentioned (lines 230-233) so copy/paste won’t break users.
.github/workflows/lint-and-test.yml-306-315 (1)

306-315: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Ensure mock servers are always stopped when tests fail.

With current flow, a failing go test exits before the stop commands execute. Use trap so cleanup runs on all exit paths.

Proposed change
           if [ "${{ matrix.module }}" = "site-agent" ]; then
             make nico-mock-server-start
             make rla-mock-server-start
+            cleanup() {
+              make nico-mock-server-stop || true
+              make rla-mock-server-stop || true
+            }
+            trap cleanup EXIT
           fi

           go test -v -race -p 1 ./${{ matrix.module }}/... -coverprofile=coverage-${{ matrix.module }}.txt -covermode=atomic 2>&1 | tee test-output-${{ matrix.module }}.txt
-
-          if [ "${{ matrix.module }}" = "site-agent" ]; then
-            make nico-mock-server-stop
-            make rla-mock-server-stop
-          fi
🤖 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 @.github/workflows/lint-and-test.yml around lines 306 - 315, The test job may
exit early on failure and skip stopping the mock servers; wrap the lifecycle of
the mocks with a trap so they are stopped on any exit. Specifically, after
starting the mocks via make nico-mock-server-start and make
rla-mock-server-start, register a trap that runs make nico-mock-server-stop and
make rla-mock-server-stop on EXIT (or ERR/INT) before running the go test
command; ensure the trap is cleared or remains in place as appropriate so the
stop targets always execute even if go test fails.
cli/pkg/commands.go-367-367 (1)

367-367: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use the actual CLI binary name in help and auth guidance.

Line 367 and Line 721 use cli, but users invoke nicocli; this makes usage/help and recovery messaging misleading.

Proposed fix
+const cliBinaryName = "nicocli"
+
 func buildActionCommand(spec *Spec, ro resolvedOp, subResource string) *cli.Command {
@@
-	usageText := "cli " + tagToCommand(ro.tag)
+	usageText := cliBinaryName + " " + tagToCommand(ro.tag)
@@
-		return nil, fmt.Errorf("no token available; run 'cli login' or set --token / NICO_TOKEN")
+		return nil, fmt.Errorf("no token available; run '%s login' or set --token / NICO_TOKEN", cliBinaryName)
 	}

Also applies to: 721-721

🤖 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 `@cli/pkg/commands.go` at line 367, The help/usage string is hardcoded to "cli
" which is wrong for users; update the construction of usage text (usageText :=
"cli " + tagToCommand(ro.tag)) and any other hardcoded "cli" occurrences (e.g.,
the message around line 721) to use the real binary name instead—either replace
the literal with "nicocli " or derive it dynamically (e.g., from a single shared
constant like CLIName or os.Args[0]) so that tagToCommand(ro.tag) is prefixed by
the actual CLI binary name in all help/auth messages.
.github/workflows/README.md-132-132 (1)

132-132: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix Docker tag format typo in docs.

Line 132 uses = in <image>:1.0.0=<short-sha>, but Docker tags should use - (as your own example already shows).

Proposed doc fix
-1. **VERSION + Git Short SHA**: `<image>:1.0.0=<short-sha>` (e.g., `nico-rest-api:1.0.0-abc1234`)
+1. **VERSION + Git Short SHA**: `<image>:1.0.0-<short-sha>` (e.g., `nico-rest-api:1.0.0-abc1234`)
🤖 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 @.github/workflows/README.md at line 132, The doc has a typo in the Docker
tag example: change the incorrect `<image>:1.0.0=<short-sha>` to use a hyphen
instead of `=` so the tag format becomes `<image>:1.0.0-<short-sha>` (e.g.,
`nico-rest-api:1.0.0-abc1234`) to match Docker tag semantics and the example
shown.
helm/README.md-44-45 (1)

44-45: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Disambiguate chart path commands for copy-paste reliability.

These commands assume the current directory is helm/. If run from repo root, charts/... fails. Either prepend helm/ in command paths or explicitly state cd helm before examples.

Example normalization (repo-root friendly)
-helm upgrade --install nico-rest charts/nico-rest/ \
+helm upgrade --install nico-rest helm/charts/nico-rest/ \
...
-helm upgrade --install nico-rest-site-agent charts/nico-rest-site-agent/ \
+helm upgrade --install nico-rest-site-agent helm/charts/nico-rest-site-agent/ \

As per coding guidelines: **/*.md: "Assess the documentation for misspellings, grammatical errors, missing documentation and correctness".

Also applies to: 68-69, 105-106, 118-119

🤖 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 `@helm/README.md` around lines 44 - 45, Update the helm command examples so
they work when run from the repository root: either prefix chart paths with
"helm/" (e.g., change "charts/nico-rest/" to "helm/charts/nico-rest/") or add an
explicit instruction to "cd helm" before the examples; apply the same
normalization to the other affected command examples noted (lines showing "helm
upgrade --install ... charts/...") so copy-paste from repo root doesn't break
and the README is unambiguous.
deploy/README.md-159-159 (1)

159-159: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix relative CLI link target.

Line 159 uses cli/README.md, which is relative to deploy/ and likely resolves incorrectly. Use ../cli/README.md so the link works from this document.

Proposed fix
-- **CLI** — install `nicocli` to interact with the deployed cluster. See [cli/README.md](cli/README.md).
+- **CLI** — install `nicocli` to interact with the deployed cluster. See [cli/README.md](../cli/README.md).

As per coding guidelines: **/*.md: "Assess the documentation for misspellings, grammatical errors, missing documentation and correctness".

🤖 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 `@deploy/README.md` at line 159, The link target "cli/README.md" in the README
is incorrect for the deploy/ document; update the link string to
"../cli/README.md" so the CLI README resolves correctly when referenced from
deploy/ (replace the occurrence of "cli/README.md" with "../cli/README.md").
.github/workflows/promotion.yaml-55-59 (1)

55-59: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Update approval message to reflect NICo branding.

The approval step message still references "Carbide REST" instead of "NICo REST", creating inconsistent user-facing messaging.

📝 Proposed fix
       - name: Approve Promote to NICo Registry
         run: |
           echo "Received build artifacts: ${{ inputs.build_artifacts }}"  
           echo "Approve Promote to NICo Registry"
-          echo "Promote Carbide REST to registry ngcr.io/0837451325059433/carbide"
+          echo "Promote NICo REST to registry ngcr.io/0837451325059433/carbide"
🤖 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 @.github/workflows/promotion.yaml around lines 55 - 59, Update the approval
step's user-facing echo to use the NICo branding: in the GitHub Actions step
with name "Approve Promote to NICo Registry" replace the echo that currently
says "Promote Carbide REST to registry ngcr.io/0837451325059433/carbide" with
"Promote NICo REST to registry ngcr.io/0837451325059433/carbide" (leave the
other echo lines unchanged).
helm/charts/nico-rest/Chart.yaml-8-9 (1)

8-9: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Remove duplicate keyword.

The keywords list contains nico twice. Remove the duplicate entry.

🧹 Proposed fix
 keywords:
   - nico
-  - nico
   - bare-metal
🤖 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 `@helm/charts/nico-rest/Chart.yaml` around lines 8 - 9, The Chart.yaml keywords
array contains a duplicate entry "nico"; locate the keywords section in
Chart.yaml and remove the repeated "nico" so each keyword appears only once
(leave a single "nico" entry in the keywords list).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 61eb3e4c-9857-42ca-8a37-6778095b5277

📥 Commits

Reviewing files that changed from the base of the PR and between 5cfe1d9 and 9e19866.

⛔ Files ignored due to path filters (2)
  • helm/charts/carbide-rest/Chart.lock is excluded by !**/*.lock
  • helm/charts/nico-rest/Chart.lock is excluded by !**/*.lock
📒 Files selected for processing (298)
  • .coderabbit.yaml
  • .github/scripts/promote-single-ngc-resource.sh
  • .github/workflows/README.md
  • .github/workflows/build-push-docker.yml
  • .github/workflows/build-push-service.yml
  • .github/workflows/helm-workflows.yml
  • .github/workflows/lint-and-test.yml
  • .github/workflows/main-build.yml
  • .github/workflows/prepare-build-info.yml
  • .github/workflows/promotion.yaml
  • .github/workflows/slack-notifications.yml
  • .gitignore
  • AGENTS.md
  • CHANGELOG.md
  • CODE_OF_CONDUCT.md
  • CONTRIBUTING.md
  • Makefile
  • README.md
  • api/cmd/api/main.go
  • api/config.yaml
  • api/internal/config/config.go
  • api/internal/config/db_test.go
  • api/internal/server/server.go
  • api/internal/server/server_test.go
  • api/pkg/api/handler/allocation.go
  • api/pkg/api/handler/allocation_test.go
  • api/pkg/api/handler/allocationconstraint.go
  • api/pkg/api/handler/allocationconstraint_test.go
  • api/pkg/api/handler/audit_entry.go
  • api/pkg/api/handler/audit_entry_test.go
  • api/pkg/api/handler/dpuextensionservice.go
  • api/pkg/api/handler/dpuextensionservice_test.go
  • api/pkg/api/handler/expectedmachine.go
  • api/pkg/api/handler/expectedmachine_test.go
  • api/pkg/api/handler/expectedpowershelf.go
  • api/pkg/api/handler/expectedpowershelf_test.go
  • api/pkg/api/handler/expectedswitch.go
  • api/pkg/api/handler/expectedswitch_test.go
  • api/pkg/api/handler/fabric.go
  • api/pkg/api/handler/fabric_test.go
  • api/pkg/api/handler/infinibandinterface.go
  • api/pkg/api/handler/infinibandinterface_test.go
  • api/pkg/api/handler/infinibandpartition.go
  • api/pkg/api/handler/infinibandpartition_test.go
  • api/pkg/api/handler/infrastructureprovider.go
  • api/pkg/api/handler/infrastructureprovider_test.go
  • api/pkg/api/handler/instance.go
  • api/pkg/api/handler/instance_test.go
  • api/pkg/api/handler/instancebatch.go
  • api/pkg/api/handler/instancebatch_test.go
  • api/pkg/api/handler/instancetype.go
  • api/pkg/api/handler/instancetype_test.go
  • api/pkg/api/handler/interface.go
  • api/pkg/api/handler/interface_test.go
  • api/pkg/api/handler/ipblock.go
  • api/pkg/api/handler/ipblock_test.go
  • api/pkg/api/handler/machine.go
  • api/pkg/api/handler/machine_test.go
  • api/pkg/api/handler/machinecapability.go
  • api/pkg/api/handler/machinecapability_test.go
  • api/pkg/api/handler/machineinstancetype.go
  • api/pkg/api/handler/machineinstancetype_test.go
  • api/pkg/api/handler/machinevalidation.go
  • api/pkg/api/handler/machinevalidation_test.go
  • api/pkg/api/handler/metadata.go
  • api/pkg/api/handler/networksecuritygroup.go
  • api/pkg/api/handler/networksecuritygroup_test.go
  • api/pkg/api/handler/nvlinkinterface.go
  • api/pkg/api/handler/nvlinkinterface_test.go
  • api/pkg/api/handler/nvlinklogicalpartition.go
  • api/pkg/api/handler/nvlinklogicalpartition_test.go
  • api/pkg/api/handler/operatingsystem.go
  • api/pkg/api/handler/operatingsystem_test.go
  • api/pkg/api/handler/rack.go
  • api/pkg/api/handler/rack_test.go
  • api/pkg/api/handler/serviceaccount.go
  • api/pkg/api/handler/serviceaccount_test.go
  • api/pkg/api/handler/site.go
  • api/pkg/api/handler/site_test.go
  • api/pkg/api/handler/sku.go
  • api/pkg/api/handler/sku_test.go
  • api/pkg/api/handler/sshkey.go
  • api/pkg/api/handler/sshkey_test.go
  • api/pkg/api/handler/sshkeygroup.go
  • api/pkg/api/handler/sshkeygroup_test.go
  • api/pkg/api/handler/stats.go
  • api/pkg/api/handler/stats_test.go
  • api/pkg/api/handler/subnet.go
  • api/pkg/api/handler/subnet_test.go
  • api/pkg/api/handler/task.go
  • api/pkg/api/handler/task_test.go
  • api/pkg/api/handler/tenant.go
  • api/pkg/api/handler/tenant_test.go
  • api/pkg/api/handler/tenantaccount.go
  • api/pkg/api/handler/tenantaccount_test.go
  • api/pkg/api/handler/tray.go
  • api/pkg/api/handler/tray_test.go
  • api/pkg/api/handler/user.go
  • api/pkg/api/handler/util/common/common.go
  • api/pkg/api/handler/util/common/common_test.go
  • api/pkg/api/handler/util/common/testing.go
  • api/pkg/api/handler/vpc.go
  • api/pkg/api/handler/vpc_test.go
  • api/pkg/api/handler/vpcpeering.go
  • api/pkg/api/handler/vpcpeering_test.go
  • api/pkg/api/handler/vpcprefix.go
  • api/pkg/api/handler/vpcprefix_test.go
  • api/pkg/api/model/audit_entry_test.go
  • api/pkg/api/model/dpuextensionservice.go
  • api/pkg/api/model/expectedmachine_test.go
  • api/pkg/api/model/health.go
  • api/pkg/api/model/infrastructureprovider.go
  • api/pkg/api/model/ipblock.go
  • api/pkg/api/model/machine.go
  • api/pkg/api/model/machine_test.go
  • api/pkg/api/model/metadata.go
  • api/pkg/api/model/networksecuritygroup.go
  • api/pkg/api/model/networksecuritygroup_test.go
  • api/pkg/api/model/rack_test.go
  • api/pkg/api/model/site.go
  • api/pkg/api/model/site_test.go
  • api/pkg/api/model/subnet.go
  • api/pkg/api/model/tenant.go
  • api/pkg/api/model/tenantaccount.go
  • api/pkg/api/model/tray_test.go
  • api/pkg/api/model/user.go
  • api/pkg/api/model/vpc.go
  • api/pkg/api/model/vpcpeering.go
  • auth/README.md
  • auth/pkg/api/handler/keycloak_test.go
  • auth/pkg/authentication/keycloak_test.go
  • auth/pkg/authentication/middleware_test.go
  • auth/pkg/authorization/org.go
  • auth/pkg/authorization/org_test.go
  • auth/pkg/config/jwks.go
  • auth/pkg/config/jwks_test.go
  • auth/pkg/config/keycloak_test.go
  • auth/pkg/config/roles.go
  • auth/pkg/core/claim/keycloak_test.go
  • auth/pkg/processors/custom_test.go
  • auth/pkg/testing/constants.go
  • cert-manager/pkg/certs/cli.go
  • cert-manager/pkg/pki/ca_helpers_test.go
  • cert-manager/pkg/pki/pki_test.go
  • cli/README.md
  • cli/cmd/cli/main.go
  • cli/pkg/app.go
  • cli/pkg/auth.go
  • cli/pkg/auth_test.go
  • cli/pkg/client.go
  • cli/pkg/commands.go
  • cli/pkg/commands_test.go
  • cli/pkg/config.go
  • cli/pkg/config_test.go
  • cli/pkg/output.go
  • cli/pkg/spec.go
  • cli/pkg/spec_test.go
  • cli/tui/commands.go
  • cli/tui/commands_test.go
  • cli/tui/configselector.go
  • cli/tui/repl.go
  • cli/tui/session.go
  • common/pkg/roles/roles.go
  • db/cmd/migrations/main.go
  • db/create-postgres-extensions.sh
  • db/pkg/db/model/audit_entry_test.go
  • db/pkg/db/model/expectedmachine.go
  • db/pkg/db/model/expectedpowershelf.go
  • db/pkg/db/model/expectedswitch.go
  • db/pkg/db/model/sku.go
  • db/pkg/db/model/tenantsite_test.go
  • db/pkg/db/model/user_test.go
  • db/pkg/db/model/vpc.go
  • db/pkg/migrations/migrations_test.go
  • db/pkg/util/testing.go
  • db/scripts/README.md
  • db/scripts/setup.sql
  • deploy/INSTALLATION.md
  • deploy/README.md
  • deploy/kind/cluster-config.yaml
  • deploy/kustomize/base/api/configmap.yaml
  • deploy/kustomize/base/api/deployment.yaml
  • deploy/kustomize/base/api/service.yaml
  • deploy/kustomize/base/cert-manager-io/cluster-issuer.yaml
  • deploy/kustomize/base/cert-manager/deployment.yaml
  • deploy/kustomize/base/cert-manager/rbac.yaml
  • deploy/kustomize/base/cert-manager/service.yaml
  • deploy/kustomize/base/common/db-creds.yaml
  • deploy/kustomize/base/common/image-pull-secret.yaml
  • deploy/kustomize/base/common/keycloak-client-secret.yaml
  • deploy/kustomize/base/common/kustomization.yaml
  • deploy/kustomize/base/common/temporal-client-cloud-cert.yaml
  • deploy/kustomize/base/common/temporal-encryption-key.yaml
  • deploy/kustomize/base/db/job.yaml
  • deploy/kustomize/base/keycloak/kustomization.yaml
  • deploy/kustomize/base/keycloak/realm-configmap.yaml
  • deploy/kustomize/base/mock-core/deployment.yaml
  • deploy/kustomize/base/mock-core/kustomization.yaml
  • deploy/kustomize/base/mock-core/service.yaml
  • deploy/kustomize/base/postgres/init-configmap.yaml
  • deploy/kustomize/base/postgres/kustomization.yaml
  • deploy/kustomize/base/site-agent/certificate.yaml
  • deploy/kustomize/base/site-agent/configmap.yaml
  • deploy/kustomize/base/site-agent/rbac.yaml
  • deploy/kustomize/base/site-agent/service.yaml
  • deploy/kustomize/base/site-agent/site-registration-secret.yaml
  • deploy/kustomize/base/site-agent/statefulset.yaml
  • deploy/kustomize/base/site-agent/temporal-client-site-agent-certs.yaml
  • deploy/kustomize/base/temporal-helm/certificates.yaml
  • deploy/kustomize/base/workflow/configmap.yaml
  • deploy/kustomize/base/workflow/deployment.yaml
  • deploy/kustomize/overlays/api/kustomization.yaml
  • deploy/kustomize/overlays/cert-manager/kustomization.yaml
  • deploy/kustomize/overlays/db/kustomization.yaml
  • deploy/kustomize/overlays/mock-core/kustomization.yaml
  • deploy/kustomize/overlays/site-agent/kustomization.yaml
  • deploy/kustomize/overlays/site-manager/kustomization.yaml
  • deploy/kustomize/overlays/workflow/kustomization.yaml
  • docker/local/Dockerfile.nico-nsm
  • docker/local/Dockerfile.nico-psm
  • docker/local/Dockerfile.nico-rest-api
  • docker/local/Dockerfile.nico-rest-cert-manager
  • docker/local/Dockerfile.nico-rest-db
  • docker/local/Dockerfile.nico-rest-mock-core
  • docker/local/Dockerfile.nico-rest-site-agent
  • docker/local/Dockerfile.nico-rest-site-manager
  • docker/local/Dockerfile.nico-rest-workflow
  • docker/local/Dockerfile.nico-rla
  • docker/production/Dockerfile.nico-nsm
  • docker/production/Dockerfile.nico-psm
  • docker/production/Dockerfile.nico-rest-api
  • docker/production/Dockerfile.nico-rest-cert-manager
  • docker/production/Dockerfile.nico-rest-db
  • docker/production/Dockerfile.nico-rest-site-agent
  • docker/production/Dockerfile.nico-rest-site-manager
  • docker/production/Dockerfile.nico-rest-workflow
  • docker/production/Dockerfile.nico-rla
  • docker/production/README.md
  • helm/README.md
  • helm/charts/carbide-rest-site-agent/templates/configmap.yaml
  • helm/charts/carbide-rest-site-agent/templates/rbac.yaml
  • helm/charts/carbide-rest/Chart.yaml
  • helm/charts/carbide-rest/charts/carbide-rest-cert-manager/Chart.yaml
  • helm/charts/carbide-rest/charts/carbide-rest-common/Chart.yaml
  • helm/charts/carbide-rest/charts/carbide-rest-site-manager/Chart.yaml
  • helm/charts/carbide-rest/charts/carbide-rest-site-manager/templates/rbac.yaml
  • helm/charts/carbide-rest/charts/carbide-rest-site-manager/templates/service.yaml
  • helm/charts/carbide-rest/templates/NOTES.txt
  • helm/charts/nico-rest-site-agent/Chart.yaml
  • helm/charts/nico-rest-site-agent/templates/_helpers.tpl
  • helm/charts/nico-rest-site-agent/templates/bootstrap.yaml
  • helm/charts/nico-rest-site-agent/templates/certificate.yaml
  • helm/charts/nico-rest-site-agent/templates/configmap.yaml
  • helm/charts/nico-rest-site-agent/templates/rbac.yaml
  • helm/charts/nico-rest-site-agent/templates/service.yaml
  • helm/charts/nico-rest-site-agent/templates/statefulset.yaml
  • helm/charts/nico-rest-site-agent/templates/temporal-certs-secret.yaml
  • helm/charts/nico-rest-site-agent/values.yaml
  • helm/charts/nico-rest/.helmignore
  • helm/charts/nico-rest/Chart.yaml
  • helm/charts/nico-rest/charts/nico-rest-api/Chart.yaml
  • helm/charts/nico-rest/charts/nico-rest-api/templates/_helpers.tpl
  • helm/charts/nico-rest/charts/nico-rest-api/templates/configmap.yaml
  • helm/charts/nico-rest/charts/nico-rest-api/templates/deployment.yaml
  • helm/charts/nico-rest/charts/nico-rest-api/templates/service.yaml
  • helm/charts/nico-rest/charts/nico-rest-api/values.yaml
  • helm/charts/nico-rest/charts/nico-rest-cert-manager/Chart.yaml
  • helm/charts/nico-rest/charts/nico-rest-cert-manager/templates/_helpers.tpl
  • helm/charts/nico-rest/charts/nico-rest-cert-manager/templates/deployment.yaml
  • helm/charts/nico-rest/charts/nico-rest-cert-manager/templates/rbac.yaml
  • helm/charts/nico-rest/charts/nico-rest-cert-manager/templates/service.yaml
  • helm/charts/nico-rest/charts/nico-rest-cert-manager/values.yaml
  • helm/charts/nico-rest/charts/nico-rest-common/Chart.yaml
  • helm/charts/nico-rest/charts/nico-rest-common/templates/_helpers.tpl
  • helm/charts/nico-rest/charts/nico-rest-common/templates/certificate.yaml
  • helm/charts/nico-rest/charts/nico-rest-common/templates/secrets.yaml
  • helm/charts/nico-rest/charts/nico-rest-common/values.yaml
  • helm/charts/nico-rest/charts/nico-rest-db/Chart.yaml
  • helm/charts/nico-rest/charts/nico-rest-db/templates/_helpers.tpl
  • helm/charts/nico-rest/charts/nico-rest-db/templates/migration-job.yaml
  • helm/charts/nico-rest/charts/nico-rest-db/values.yaml
  • helm/charts/nico-rest/charts/nico-rest-site-manager/Chart.yaml
  • helm/charts/nico-rest/charts/nico-rest-site-manager/crds/site.yaml
  • helm/charts/nico-rest/charts/nico-rest-site-manager/templates/_helpers.tpl
  • helm/charts/nico-rest/charts/nico-rest-site-manager/templates/certificate.yaml
  • helm/charts/nico-rest/charts/nico-rest-site-manager/templates/deployment.yaml
  • helm/charts/nico-rest/charts/nico-rest-site-manager/templates/rbac.yaml
  • helm/charts/nico-rest/charts/nico-rest-site-manager/templates/service.yaml
  • helm/charts/nico-rest/charts/nico-rest-site-manager/values.yaml
  • helm/charts/nico-rest/charts/nico-rest-workflow/Chart.yaml
  • helm/charts/nico-rest/charts/nico-rest-workflow/templates/_helpers.tpl
  • helm/charts/nico-rest/charts/nico-rest-workflow/templates/configmap.yaml
  • helm/charts/nico-rest/charts/nico-rest-workflow/templates/deployment-cloud-worker.yaml
  • helm/charts/nico-rest/charts/nico-rest-workflow/templates/deployment-site-worker.yaml
  • helm/charts/nico-rest/charts/nico-rest-workflow/values.yaml
  • helm/charts/nico-rest/templates/NOTES.txt
  • helm/charts/nico-rest/values.yaml
  • ipam/bun_test.go
💤 Files with no reviewable changes (9)
  • helm/charts/carbide-rest/Chart.yaml
  • helm/charts/carbide-rest/charts/carbide-rest-site-manager/Chart.yaml
  • helm/charts/carbide-rest/charts/carbide-rest-common/Chart.yaml
  • helm/charts/carbide-rest-site-agent/templates/configmap.yaml
  • helm/charts/carbide-rest/charts/carbide-rest-cert-manager/Chart.yaml
  • helm/charts/carbide-rest/templates/NOTES.txt
  • helm/charts/carbide-rest-site-agent/templates/rbac.yaml
  • helm/charts/carbide-rest/charts/carbide-rest-site-manager/templates/service.yaml
  • helm/charts/carbide-rest/charts/carbide-rest-site-manager/templates/rbac.yaml

Comment on lines +384 to +387
"service": "nico-psm",
"image_ref": "${{ needs.build-nico-psm.outputs.image_ref }}",
"binary_resource": "${{ needs.build-nico-psm.ngc_binary_resource }}",
"image_resource": "${{ needs.build-nico-psm.outputs.ngc_image_resource }}"
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 | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Verify all needs-based artifact fields use .outputs.<name>
rg -nP 'needs\.build-[a-z0-9-]+\.(image_ref|ngc_binary_resource|ngc_image_resource)' .github/workflows/build-push-docker.yml

Repository: NVIDIA/infra-controller-rest

Length of output: 160


🏁 Script executed:

# Check the full context around lines 384-387
sed -n '375,395p' .github/workflows/build-push-docker.yml

Repository: NVIDIA/infra-controller-rest

Length of output: 1162


🏁 Script executed:

# Search for the build-nico-psm job definition and its outputs
rg -n 'build-nico-psm' .github/workflows/build-push-docker.yml | head -20

Repository: NVIDIA/infra-controller-rest

Length of output: 505


🏁 Script executed:

# Verify the job definition has outputs declared
rg -A 10 'jobs:' .github/workflows/build-push-docker.yml | grep -A 10 'build-nico-psm'

Repository: NVIDIA/infra-controller-rest

Length of output: 54


Correct the output accessor for nico-psm binary resource.

Line 386 references needs.build-nico-psm.ngc_binary_resource without the .outputs accessor. This produces an invalid or empty value in the aggregated artifacts JSON. All other services in this block correctly use the .outputs syntax for accessing job outputs.

Proposed fix
-              "binary_resource": "${{ needs.build-nico-psm.ngc_binary_resource }}",
+              "binary_resource": "${{ needs.build-nico-psm.outputs.ngc_binary_resource }}",
📝 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
"service": "nico-psm",
"image_ref": "${{ needs.build-nico-psm.outputs.image_ref }}",
"binary_resource": "${{ needs.build-nico-psm.ngc_binary_resource }}",
"image_resource": "${{ needs.build-nico-psm.outputs.ngc_image_resource }}"
"service": "nico-psm",
"image_ref": "${{ needs.build-nico-psm.outputs.image_ref }}",
"binary_resource": "${{ needs.build-nico-psm.outputs.ngc_binary_resource }}",
"image_resource": "${{ needs.build-nico-psm.outputs.ngc_image_resource }}"
🤖 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 @.github/workflows/build-push-docker.yml around lines 384 - 387, The
aggregated artifacts JSON uses an incorrect output accessor for the nico-psm
binary resource: change the reference from
needs.build-nico-psm.ngc_binary_resource to use the outputs object
(needs.build-nico-psm.outputs.ngc_binary_resource) so it matches the other
services and returns the actual job output; update the "binary_resource" value
for the "nico-psm" service accordingly.

Comment on lines 143 to 145
# Helm chart version: read from Chart.yaml (umbrella chart as source of truth)
HELM_VERSION=$(grep '^version:' helm/charts/carbide-rest/Chart.yaml | awk '{print $2}')
HELM_VERSION=$(grep '^version:' helm/charts/nico-rest/Chart.yaml | awk '{print $2}')
echo "helm_version=$HELM_VERSION" >> $GITHUB_OUTPUT
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 | 🟠 Major | ⚡ Quick win

Fail fast if Helm version cannot be resolved.

If the chart file path changes or parsing fails, HELM_VERSION becomes empty and downstream jobs get invalid metadata. Add explicit file/value validation.

Proposed change
-          # Helm chart version: read from Chart.yaml (umbrella chart as source of truth)
-          HELM_VERSION=$(grep '^version:' helm/charts/nico-rest/Chart.yaml | awk '{print $2}')
+          # Helm chart version: read from Chart.yaml (umbrella chart as source of truth)
+          CHART_FILE="helm/charts/nico-rest/Chart.yaml"
+          if [ ! -f "$CHART_FILE" ]; then
+            echo "ERROR: $CHART_FILE not found"
+            exit 1
+          fi
+          HELM_VERSION=$(awk -F': *' '$1=="version"{print $2; exit}' "$CHART_FILE")
+          if [ -z "$HELM_VERSION" ]; then
+            echo "ERROR: failed to parse version from $CHART_FILE"
+            exit 1
+          fi
           echo "helm_version=$HELM_VERSION" >> $GITHUB_OUTPUT
📝 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
# Helm chart version: read from Chart.yaml (umbrella chart as source of truth)
HELM_VERSION=$(grep '^version:' helm/charts/carbide-rest/Chart.yaml | awk '{print $2}')
HELM_VERSION=$(grep '^version:' helm/charts/nico-rest/Chart.yaml | awk '{print $2}')
echo "helm_version=$HELM_VERSION" >> $GITHUB_OUTPUT
# Helm chart version: read from Chart.yaml (umbrella chart as source of truth)
CHART_FILE="helm/charts/nico-rest/Chart.yaml"
if [ ! -f "$CHART_FILE" ]; then
echo "ERROR: $CHART_FILE not found"
exit 1
fi
HELM_VERSION=$(awk -F': *' '$1=="version"{print $2; exit}' "$CHART_FILE")
if [ -z "$HELM_VERSION" ]; then
echo "ERROR: failed to parse version from $CHART_FILE"
exit 1
fi
echo "helm_version=$HELM_VERSION" >> $GITHUB_OUTPUT
🤖 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 @.github/workflows/prepare-build-info.yml around lines 143 - 145, After
extracting HELM_VERSION from helm/charts/nico-rest/Chart.yaml, add explicit
validation: verify the Chart.yaml file exists/readable and that the HELM_VERSION
variable is non-empty; if either check fails, print a clear error to stderr
(including the path and the parsed value) and exit non‑zero so the workflow
fails fast instead of writing an empty helm_version to GITHUB_OUTPUT. Reference
the HELM_VERSION variable and the existing grep/awk extraction block so you
insert the file-existence check and a conditional that aborts with exit 1 when
HELM_VERSION is empty.

Comment thread .gitignore

build/
/carbide-rest
/nico-rest
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 | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Search for any lingering references to carbide-rest across the repository.

# Search for carbide-rest references (case-insensitive to catch variations)
rg -i 'carbide-rest' --type-not gitignore -C2

Repository: NVIDIA/infra-controller-rest

Length of output: 106


🏁 Script executed:

#!/bin/bash
# Search for carbide-rest references with corrected syntax
rg -i 'carbide-rest' --glob '!.gitignore' -C2

Repository: NVIDIA/infra-controller-rest

Length of output: 50386


🏁 Script executed:

# Also verify the .gitignore change
cat -n .gitignore | head -25

Repository: NVIDIA/infra-controller-rest

Length of output: 966


🏁 Script executed:

# Check for any carbide-rest or carbide references in the entire codebase
rg -i 'carbide' | head -50

Repository: NVIDIA/infra-controller-rest

Length of output: 5283


Incomplete rebranding—critical files still reference carbide-rest.

While the .gitignore change is syntactically sound, the renaming effort is incomplete across the codebase. Multiple critical files retain outdated references:

  • site-manager/pkg/sitemgr/cli.go (line ~70): Default namespace still hardcoded to "carbide-rest" instead of "nico-rest"
  • Helm charts: Image names in values.yaml files still reference carbide-rest-* variants (nico-rest-site-agent, nico-rest-db, etc.)
  • Kubernetes manifests: Service, RBAC, Certificate, and Deployment files in deploy/kustomize/base/site-manager/ still use carbide-rest identifiers

The .gitignore entry correctly targets the new directory name, but the namespace default in cli.go contradicts this intent and will prevent proper deployment. Ensure all generation scripts, configuration defaults, and infrastructure definitions are updated to reflect the new namespace.

🤖 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 @.gitignore at line 17, The repo rename to "nico-rest" is incomplete: update
all remaining hardcoded "carbide-rest" identifiers to "nico-rest" so defaults
and manifests align with the new .gitignore; specifically change the default
namespace value in site-manager/pkg/sitemgr/cli.go (where the default namespace
is set to "carbide-rest") to "nico-rest", update image names in Helm values.yaml
files (replace any `carbide-rest-*` with `nico-rest-*`), and replace identifiers
in Kubernetes manifests under deploy/kustomize/base/site-manager/ (Services,
RBAC, Certificates, Deployments) to use "nico-rest" consistently; run a
repository-wide search for "carbide-rest" to ensure no remaining references and
update any generation scripts or configuration defaults that emit the old name.

Comment on lines +296 to 302
func InitMetricsServer(e *echo.Echo, cfg *config.Config) *echo.Echo {
ep := echo.New()
ep.HideBanner = true

conf := echoPrometheus.MiddlewareConfig{
Subsystem: "carbide_api",
Subsystem: fmt.Sprintf("%s_api", cfg.GetAPIName()),
Skipper: api.MetricsURLSkipper,
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 | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Locate GetAPIName and apiName defaults =="
rg -n --type=go -C3 '\bGetAPIName\s*\('
rg -n --type=go -C2 'apiName\s*[:=]\s*"[^"]+"'

echo
echo "== Validate derived <apiName>_api against Prometheus naming rules =="
python - <<'PY'
import re
from pathlib import Path

name_assign = re.compile(r'apiName\s*[:=]\s*"([^"]+)"')
valid = re.compile(r'^[a-zA-Z_:][a-zA-Z0-9_:]*$')

found = []
for p in Path(".").rglob("*.go"):
    try:
        text = p.read_text(encoding="utf-8")
    except Exception:
        continue
    for m in name_assign.finditer(text):
        api_name = m.group(1)
        subsystem = f"{api_name}_api"
        found.append((str(p), api_name, subsystem, bool(valid.match(subsystem))))

if not found:
    print("No explicit apiName literals found; inspect GetAPIName source manually.")
else:
    for path, api_name, subsystem, ok in found:
        status = "VALID" if ok else "INVALID"
        print(f"{status}: apiName='{api_name}' -> subsystem='{subsystem}' ({path})")
PY

Repository: NVIDIA/infra-controller-rest

Length of output: 6406


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Find ConfigAPIName definition =="
rg -n --type=go 'ConfigAPIName' -B2 -A2

echo
echo "== Check config validation and how ConfigAPIName is set =="
rg -n --type=go 'GetString.*ConfigAPIName|viper.*GetString' api/internal/config/config.go -B3 -A3

echo
echo "== Look for config file examples or environment variable binding =="
fd -t f '\.yml|\.yaml|\.toml|\.env' | head -20

Repository: NVIDIA/infra-controller-rest

Length of output: 2358


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Examine echoPrometheus library usage and validation =="
rg -n --type=go 'echoPrometheus|MiddlewareConfig' api/internal/server/server.go -B5 -A5

echo
echo "== Check if there are any tests with invalid API names =="
rg -n --type=go 'GetAPIName|apiName' api/internal/config/config.go -B5 -A10

Repository: NVIDIA/infra-controller-rest

Length of output: 2711


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Locate and check viper configuration binding =="
fd -t f config.go | xargs grep -l "viper\|venv" | head -5
rg -n 'BindEnv|BindFlag|Set.*ConfigAPIName' --type=go

echo
echo "== Check imports to understand config library =="
head -30 api/internal/config/config.go | grep -E '^import|viper'

Repository: NVIDIA/infra-controller-rest

Length of output: 320


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Check actual config files for api.name values =="
rg -n 'api\.name|api:.*name' api/config.yaml deploy/kustomize/base/api/configmap.yaml 2>/dev/null || echo "Pattern not found or files missing"

echo
echo "== Check if there's any validation logic for api name =="
rg -n --type=go 'api\.name|APIName' api/internal/config/config.go -B10 -A2 | head -50

echo
echo "== Look for any helper validation functions =="
rg -n --type=go 'sanitize|validate|valid' api/internal/config/config.go --ignore-case

echo
echo "== Check if echoPrometheus returns errors on invalid subsystem =="
rg -n --type=go 'NewMiddleware|error|Error' api/internal/server/server.go | grep -A5 -B5 'echoPrometheus\|InitMetrics'

Repository: NVIDIA/infra-controller-rest

Length of output: 4033


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Read actual config.yaml to see default/example api name =="
cat api/config.yaml 2>/dev/null | head -100

echo
echo "== Check deployment configs =="
grep -r "api.name\|api:\|apiName" deploy/kustomize/base/api/ 2>/dev/null | head -20

Repository: NVIDIA/infra-controller-rest

Length of output: 2175


🏁 Script executed:

#!/bin/bash
set -eulo pipefail

echo "== Check if there are tests for invalid API names or metric registration =="
rg -n --type=go 'GetAPIName|Prometheus|subsystem' api/internal/server/server_test.go -B3 -A3

echo
echo "== Check if echoPrometheus.NewMiddlewareWithConfig has error handling =="
rg -n 'NewMiddlewareWithConfig' api/internal/server/server.go -B2 -A5

echo
echo "== Search for any Prometheus validation or sanitization =="
rg -n --type=go 'Prometheus|metric|subsystem' . -i --type=go | grep -i 'valid\|sanitize\|clean\|format'

Repository: NVIDIA/infra-controller-rest

Length of output: 2780


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Check Prometheus metric naming rules documentation in codebase =="
rg -n --type=go 'metric.*name|subsystem' . -B2 -A2 | grep -i 'rule\|valid\|format\|pattern'

echo
echo "== Look for any github.com/prometheus imports or usages =="
rg -n 'prometheus|metric' api/internal/server/server.go -i

echo
echo "== Check if there's existing sanitization anywhere else =="
rg -n --type=go 'Sanitize|Clean|Format' . | head -20

Repository: NVIDIA/infra-controller-rest

Length of output: 3810


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Check what happens when NewMiddlewareWithConfig is called - look at full InitMetricsServer =="
sed -n '296,315p' api/internal/server/server.go

echo
echo "== Search for any comment or documentation about API name format =="
rg -n -B5 'api\.name|ConfigAPIName|GetAPIName' api/internal/config/config.go | grep -A5 -B5 '//'

Repository: NVIDIA/infra-controller-rest

Length of output: 1666


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Check how echoPrometheus handles invalid subsystem names =="
rg -n 'type.*MiddlewareConfig|Subsystem' --type=go api/internal/server/server.go

echo
echo "== Verify if Validate() method in Config covers api.name =="
sed -n '321,400p' api/internal/config/config.go

echo
echo "== Search for any environment variable binding or override =="
rg -n 'BindEnv|viper.*Bind|SetEnv' api/internal/config/config.go

Repository: NVIDIA/infra-controller-rest

Length of output: 2888


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Check if there's any documentation or comment about expected API name format =="
rg -n 'api\.name|GetAPIName' --type=go -B5 -A3 | grep -E '(//|/\*|\*/)' -A2 -B2

echo
echo "== Look for any test or example showing what api.name can be =="
find . -name '*.yaml' -o -name '*.yml' | xargs grep -l 'api' 2>/dev/null | head -5 | xargs grep 'api:' -A5 2>/dev/null

echo
echo "== Check if echoPrometheus library itself validates or sanitizes =="
rg -n 'github\.com/labstack/echo-contrib' . 2>/dev/null | head -3

Repository: NVIDIA/infra-controller-rest

Length of output: 6582


Sanitize cfg.GetAPIName() before using it as Prometheus subsystem.

Line 301 constructs the subsystem directly from config without validation. The config system accepts arbitrary values for api.name via YAML, environment variables, or programmatic override, with no format constraints. If the API name contains characters invalid in Prometheus metrics (e.g., hyphens), metric registration will fail at runtime.

Proposed hardening
 func InitMetricsServer(e *echo.Echo, cfg *config.Config) *echo.Echo {
 	ep := echo.New()
 	ep.HideBanner = true
 
+	subsystem := sanitizePromSubsystem(cfg.GetAPIName()) + "_api"
 	conf := echoPrometheus.MiddlewareConfig{
-		Subsystem: fmt.Sprintf("%s_api", cfg.GetAPIName()),
+		Subsystem: subsystem,
 		Skipper:   api.MetricsURLSkipper,
 	}
@@
 	return ep
 }
+
+func sanitizePromSubsystem(name string) string {
+	if name == "" {
+		return "api"
+	}
+	b := make([]rune, 0, len(name))
+	for _, r := range name {
+		ok := (r >= 'a' && r <= 'z') ||
+			(r >= 'A' && r <= 'Z') ||
+			(r >= '0' && r <= '9') ||
+			r == '_' || r == ':'
+		if ok {
+			b = append(b, r)
+		} else {
+			b = append(b, '_')
+		}
+	}
+	// First rune cannot be a digit.
+	if len(b) > 0 && b[0] >= '0' && b[0] <= '9' {
+		b = append([]rune{'_'}, b...)
+	}
+	return string(b)
+}
📝 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
func InitMetricsServer(e *echo.Echo, cfg *config.Config) *echo.Echo {
ep := echo.New()
ep.HideBanner = true
conf := echoPrometheus.MiddlewareConfig{
Subsystem: "carbide_api",
Subsystem: fmt.Sprintf("%s_api", cfg.GetAPIName()),
Skipper: api.MetricsURLSkipper,
func InitMetricsServer(e *echo.Echo, cfg *config.Config) *echo.Echo {
ep := echo.New()
ep.HideBanner = true
subsystem := sanitizePromSubsystem(cfg.GetAPIName()) + "_api"
conf := echoPrometheus.MiddlewareConfig{
Subsystem: subsystem,
Skipper: api.MetricsURLSkipper,
}
return ep
}
func sanitizePromSubsystem(name string) string {
if name == "" {
return "api"
}
b := make([]rune, 0, len(name))
for _, r := range name {
ok := (r >= 'a' && r <= 'z') ||
(r >= 'A' && r <= 'Z') ||
(r >= '0' && r <= '9') ||
r == '_' || r == ':'
if ok {
b = append(b, r)
} else {
b = append(b, '_')
}
}
// First rune cannot be a digit.
if len(b) > 0 && b[0] >= '0' && b[0] <= '9' {
b = append([]rune{'_'}, b...)
}
return string(b)
}
🤖 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 `@api/internal/server/server.go` around lines 296 - 302, InitMetricsServer
currently uses cfg.GetAPIName() directly for the Prometheus Subsystem
(echoPrometheus.MiddlewareConfig.Subsystem) which can contain invalid chars;
update InitMetricsServer to sanitize the API name before use by normalizing to a
safe Prometheus subsystem token (e.g., replace or remove invalid characters such
as hyphens, spaces, and non-alphanumerics, collapse consecutive separators, and
ensure it starts with a letter or underscore), and fall back to a fixed safe
default like "api" if the sanitized result is empty; apply this transformation
just before creating the MiddlewareConfig.Subsystem so all calls that reference
cfg.GetAPIName() in InitMetricsServer use the sanitized value.

Comment on lines 61 to +64
// @Param org path string true "Name of NGC organization"
// @Param site_id query string true "Filter by site ID"
// @Success 200 {object} model.APIUser
// @Router /v2/org/{org}/carbide/machine-capability [get]
// @Router /v2/org/{org}/nico/machine-capability [get]
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 | 🟠 Major | ⚡ Quick win

Swagger annotation block is still inconsistent with the handler contract

Line 64 correctly moves the route to /nico, but the same doc block still advertises mismatched request/response metadata (for example, Line 62 uses site_id while handler reads siteId, and Line 63 advertises model.APIUser although this endpoint returns machine capabilities). Please update this annotation block fully so generated OpenAPI stays accurate.

Suggested annotation fix
 // Handle godoc
-// `@Summary` Return information about the current user
-// `@Description` Get basic information about the user making the request
-// `@Tags` user
+// `@Summary` Return distinct machine capabilities
+// `@Description` Get distinct machine capabilities for an organization, optionally filtered
+// `@Tags` machine-capability
 // `@Accept` */*
 // `@Produce` json
 // `@Security` ApiKeyAuth
 // `@Param` org path string true "Name of NGC organization"
-// `@Param` site_id query string true "Filter by site ID"
-// `@Success` 200 {object} model.APIUser
+// `@Param` siteId query string false "Filter by site ID"
+// `@Success` 200 {array} model.APIMachineCapability
 // `@Router` /v2/org/{org}/nico/machine-capability [get]
🤖 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 `@api/pkg/api/handler/machinecapability.go` around lines 61 - 64, The Swagger
doc block above the handler is inconsistent: update the annotation in
machinecapability.go to match the handler contract by using the exact parameter
names and response shape the handler expects—change the query param from
"site_id" to "siteId" (keep the path param "org" as-is), ensure the route stays
"/v2/org/{org}/nico/machine-capability [get]", and change the Success line to
reflect the actual return type (e.g., 200 {array} model.MachineCapability or the
correct model name the handler returns) so generated OpenAPI matches the
handler.

Comment on lines +42 to +44
name: nico
user: nico
password: nico
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 | 🟠 Major | 🏗️ Heavy lift

Move database credentials out of ConfigMap data.

db.user and db.password are plaintext in a ConfigMap. This weakens secret handling and broadens accidental exposure risk. Use a Kubernetes Secret for credentials and inject them via mounted file/env reference instead.

🤖 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 `@deploy/kustomize/base/api/configmap.yaml` around lines 42 - 44, ConfigMap
currently contains plaintext DB credentials (keys "user" and "password" under
the ConfigMap with name "nico"); remove those keys from the ConfigMap data and
create a Kubernetes Secret containing db.user and db.password instead, then
update any workloads that consume this ConfigMap to read credentials from the
Secret (via env/secretKeyRef or a mounted volume) while keeping non-sensitive
values like "name" in the ConfigMap; search for usages of the ConfigMap name
"nico" and change the Pod/Deployment env or volume references to use the new
Secret to inject db.user and db.password securely.

Comment on lines +34 to 37
name: nico
user: nico
password: nico

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 | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect workflow configmaps and overlays for password overrides/patches.
rg -n -C3 'nico-rest-workflow-config|db:|name:\s*nico|user:\s*nico|password:\s*nico|secret|patches|patchesStrategicMerge' --glob '*.y*ml'

Repository: NVIDIA/infra-controller-rest

Length of output: 50385


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Find kustomize structure and overlays
find . -name "kustomization.yaml" -o -name "kustomization.yml" | grep -E "workflow|deploy" | head -20

# Look for deployment/overlay directories
fd -t d "overlay|prod|staging|dev" --path "*kustomize*" | head -20

Repository: NVIDIA/infra-controller-rest

Length of output: 1350


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Check the actual configmap file mentioned in the review
find . -path "*deploy/kustomize/base/workflow/configmap.yaml" -exec cat {} \;

# Also search more broadly for workflow configmaps
find . -path "*configmap.yaml" | grep workflow

Repository: NVIDIA/infra-controller-rest

Length of output: 1877


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Search for kustomize patches that might override credentials
rg -l "patchesStrategicMerge|patchesJson6902" --glob "*/kustomization.*" | head -20

# Look for overlay structure with credential patches
rg -B5 -A10 "name.*nico|password.*nico" --glob "*/kustomization*" 2>/dev/null || true

Repository: NVIDIA/infra-controller-rest

Length of output: 221


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Check the base kustomization.yaml for workflow
echo "=== BASE KUSTOMIZATION ==="
cat ./deploy/kustomize/base/workflow/kustomization.yaml

echo ""
echo "=== OVERLAY KUSTOMIZATION ==="
cat ./deploy/kustomize/overlays/workflow/kustomization.yaml

Repository: NVIDIA/infra-controller-rest

Length of output: 2519


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Search for any patches or strategic merge patches related to workflow config
echo "=== Searching for patches in workflow directories ==="
find ./deploy/kustomize -path "*workflow*" -type f \( -name "*.yaml" -o -name "*.yml" \) -exec grep -l "patch\|secret\|name.*nico" {} \;

echo ""
echo "=== Check for overlay subdirectories ==="
ls -la ./deploy/kustomize/overlays/workflow/ 2>/dev/null || echo "No overlay subdirs"

Repository: NVIDIA/infra-controller-rest

Length of output: 500


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Check the deployment to see if it references secrets for DB credentials
echo "=== WORKFLOW DEPLOYMENT ==="
cat ./deploy/kustomize/base/workflow/deployment.yaml | head -100

Repository: NVIDIA/infra-controller-rest

Length of output: 3071


Confirm that production overlays use secret-backed database credentials instead of the hardcoded base defaults.

The base configmap embeds password: nico inline. The current overlay references the base without patching this ConfigMap field, and the deployment reads configuration directly from the ConfigMap without external secret injection. Ensure production deployments override db.password through either:

  • A Kustomize strategic merge patch on the ConfigMap data section
  • Mounting database credentials as secrets and referencing them via environment variables in the deployment

This prevents shipping plaintext default credentials to production environments.

🤖 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 `@deploy/kustomize/base/workflow/configmap.yaml` around lines 34 - 37, The base
ConfigMap exposes plaintext credentials (data.password = "nico") which must not
be used in production; update production overlays to override the base by either
(a) applying a Kustomize strategicMergePatch to remove/replace the ConfigMap
data.password with a reference to a Secret, or (b) create a Secret (via
secretGenerator or Kubernetes Secret manifest) and modify the Deployment spec to
read DB credentials from the Secret (use env valueFrom.secretKeyRef or
volumeMount with secretKeyRef) instead of reading directly from the base
ConfigMap; ensure you target the ConfigMap data key "password" and the
Deployment's env variables that currently reference the ConfigMap so production
no longer ships plaintext defaults.

Comment on lines 59 to +60
# -- Plain-text password. Ignored when secrets.dbCreds is set.
password: forge
password: nico
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 | 🟠 Major | ⚡ Quick win

Avoid shipping a static default DB password in chart defaults.

Using a predictable default (nico) makes accidental insecure deployments too easy. Prefer empty-by-default and require secrets.dbCreds or environment-specific overrides.

Proposed change
   db:
     host: postgres.postgres
     port: 5432
     name: nico
     user: nico
     # -- Plain-text password. Ignored when secrets.dbCreds is set.
-    password: nico
+    password: ""
📝 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
# -- Plain-text password. Ignored when secrets.dbCreds is set.
password: forge
password: nico
# -- Plain-text password. Ignored when secrets.dbCreds is set.
password: ""
🤖 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 `@helm/charts/nico-rest/charts/nico-rest-workflow/values.yaml` around lines 59
- 60, Remove the static default DB password "nico" from the chart values and
make the DB password empty-by-default (e.g., set the top-level value for
password to an empty string or placeholder) so deployments must explicitly
provide credentials via secrets.dbCreds or environment-specific overrides;
update the values.yaml entry for "password" and add a short comment clarifying
that a value must be provided through secrets.dbCreds (or via environment) and
that leaving it empty will fail validation/require a secret.

Comment thread Makefile
Comment on lines 337 to +338
@echo "Waiting for API service..."
kubectl -n carbide-rest rollout status deployment/carbide-rest-api --timeout=120s || true
kubectl -n nico-rest rollout status deployment/nico-rest-api --timeout=120s || true
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 | 🟠 Major | ⚡ Quick win

Do not swallow API rollout failures in kind-apply.

kind-deploy is the happy-path local bring-up target, so masking the API rollout with || true lets the target report success while the control plane is still down. If only bootstrap-dependent workloads need soft failure handling, keep that exception scoped to those workloads.

Suggested fix
-	kubectl -n nico-rest rollout status deployment/nico-rest-api --timeout=120s || true
+	kubectl -n nico-rest rollout status deployment/nico-rest-api --timeout=120s
📝 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
@echo "Waiting for API service..."
kubectl -n carbide-rest rollout status deployment/carbide-rest-api --timeout=120s || true
kubectl -n nico-rest rollout status deployment/nico-rest-api --timeout=120s || true
`@echo` "Waiting for API service..."
kubectl -n nico-rest rollout status deployment/nico-rest-api --timeout=120s
🤖 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 `@Makefile` around lines 337 - 338, The Makefile currently swallows failures
for the API rollout by appending "|| true" to the kubectl rollout status for
deployment/nico-rest-api in the kind-apply/ kind-deploy flow; remove the "||
true" so the target fails on rollout errors, or if you only intend soft-failure
for bootstrap-only workloads, move the "|| true" to those specific kubectl
rollout lines instead of the nico-rest-api line (identify and edit the kubectl
-n nico-rest rollout status deployment/nico-rest-api --timeout=120s invocation
in the Makefile and either delete the "|| true" or relocate it to the
bootstrap-specific deployment rollout commands).

Comment thread Makefile
Comment on lines 477 to +479
@echo "Setting up common secrets..."
kubectl apply -k deploy/kustomize/base/common
kubectl -n carbide-rest wait --for=condition=Ready certificate/temporal-client-cloud-cert --timeout=240s || true
kubectl -n nico-rest wait --for=condition=Ready certificate/temporal-client-cloud-cert --timeout=240s || true
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 | 🟠 Major | ⚡ Quick win

Fail fast when the Temporal client certificate is not ready.

The API and workflow workers depend on temporal-client-cloud-cert, so continuing past a failed wait only defers the real error into later rollout failures. This target should stop at the missing certificate.

Suggested fix
-	kubectl -n nico-rest wait --for=condition=Ready certificate/temporal-client-cloud-cert --timeout=240s || true
+	kubectl -n nico-rest wait --for=condition=Ready certificate/temporal-client-cloud-cert --timeout=240s
🤖 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 `@Makefile` around lines 477 - 479, The Makefile currently swallows failures
when waiting for the Temporal client cert because the kubectl wait command ends
with "|| true"; remove that fallback so the target fails fast if the certificate
(certificate/temporal-client-cloud-cert) is not Ready—either delete "|| true" or
replace it with "|| exit 1" (or rely on set -e) so the Makefile stops
immediately on a failed kubectl -n nico-rest wait for the certificate.

- nico-rest-site-agent: also mount mTLS certs at /etc/carbide so the
  chart works against the not-yet-renamed carbide-rest-site-agent image
  in addition to the new nico-rest-site-agent binary.
- Revert image.name to carbide-rest-* in nico-rest-{api,cert-manager,
  db,site-manager,workflow} and nico-rest-site-agent values.yaml — the
  published images still use the carbide-* names, so the chart renames
  alone shouldn't change the image references.
- nico-rest-site-manager rbac: add the missing "create" verb on
  forge.nvidia.io/sites (already present for nico.nvidia.io/sites);
  required while legacy site agents still create Site CRs in the
  forge group.
- nico-rest-api configmap: drop the trailing "-" on the
  validateAuth include so the rendered ConfigMap has no leading
  blank line.

Signed-off-by: Shayan Namaghi <snamaghi@nvidia.com>
@shayan1995 shayan1995 force-pushed the feat/rename-ncx-to-nico branch from 9e19866 to 6c297ee Compare May 8, 2026 22:03
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 8, 2026

🔐 TruffleHog Secret Scan

No secrets or credentials found!

Your code has been scanned for 700+ types of secrets and credentials. All clear! 🎉

🔗 View scan details

🕐 Last updated: 2026-05-08 22:04:10 UTC | Commit: 6c297ee

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