Skip to content
This repository was archived by the owner on Sep 9, 2026. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion internal/cmd/cli/create/cluster/create_cluster_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,8 @@ func (c *runnerContext) applyOptionalSpecFields(
func (c *runnerContext) createCluster(ctx context.Context, spec *publicv1.ClusterSpec) error {
cluster := publicv1.Cluster_builder{
Metadata: publicv1.Metadata_builder{
Name: c.args.name,
Name: c.args.name,
Tenant: config.TenantFromContext(ctx),
}.Build(),
Spec: spec,
}.Build()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,8 @@ func (c *runnerContext) run(cmd *cobra.Command, args []string) error {

computeInstance := publicv1.ComputeInstance_builder{
Metadata: publicv1.Metadata_builder{
Name: c.args.name,
Name: c.args.name,
Tenant: config.TenantFromContext(ctx),
}.Build(),
Spec: specResult,
}.Build()
Expand Down
4 changes: 4 additions & 0 deletions internal/cmd/cli/create/create_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,13 +154,17 @@ func (c *runnerContext) run(cmd *cobra.Command, args []string) error {
if err != nil {
return err
}
tenant := config.TenantFromContext(ctx)
for i, object := range objects {
objectDesc := object.ProtoReflect().Descriptor()
objectType := string(objectDesc.FullName())
objectHelper := helper.Lookup(objectType)
if objectHelper == nil {
return fmt.Errorf("input object at index %d is of an unknown type '%s'", i, objectType)
}
if tenant != "" && objectHelper.IsTenantScoped() {
objectHelper.SetTenant(object, tenant)
}
object, err = objectHelper.Create(ctx, object)
if err != nil {
return fmt.Errorf("failed to create object at index %d: %w", i, err)
Expand Down
2 changes: 1 addition & 1 deletion internal/cmd/cli/create/publicip/create_publicip_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ func (c *runnerContext) run(cmd *cobra.Command, args []string) error {
Pool: pool.GetId(),
}
publicIP := publicv1.PublicIP_builder{
Metadata: publicv1.Metadata_builder{Name: c.args.name}.Build(),
Metadata: publicv1.Metadata_builder{Name: c.args.name, Tenant: config.TenantFromContext(ctx)}.Build(),
Spec: spec.Build(),
}.Build()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ func (c *runnerContext) run(cmd *cobra.Command, args []string) error {
client := publicv1.NewSecurityGroupsClient(conn)

sg := publicv1.SecurityGroup_builder{
Metadata: publicv1.Metadata_builder{Name: c.args.name}.Build(),
Metadata: publicv1.Metadata_builder{Name: c.args.name, Tenant: config.TenantFromContext(ctx)}.Build(),
Spec: publicv1.SecurityGroupSpec_builder{
VirtualNetwork: vn.GetId(),
Ingress: ingress,
Expand Down
2 changes: 1 addition & 1 deletion internal/cmd/cli/create/subnet/create_subnet_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ func (c *runnerContext) run(cmd *cobra.Command, args []string) error {
spec.Ipv6Cidr = &c.args.ipv6Cidr
}
subnet := publicv1.Subnet_builder{
Metadata: publicv1.Metadata_builder{Name: c.args.name}.Build(),
Metadata: publicv1.Metadata_builder{Name: c.args.name, Tenant: config.TenantFromContext(ctx)}.Build(),
Spec: spec.Build(),
}.Build()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ func (c *runnerContext) run(cmd *cobra.Command, args []string) error {
spec.Ipv6Cidr = &c.args.ipv6Cidr
}
vn := publicv1.VirtualNetwork_builder{
Metadata: publicv1.Metadata_builder{Name: c.args.name}.Build(),
Metadata: publicv1.Metadata_builder{Name: c.args.name, Tenant: config.TenantFromContext(ctx)}.Build(),
Spec: spec.Build(),
}.Build()

Expand Down
28 changes: 27 additions & 1 deletion internal/cmd/cli/root_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"github.com/osac-project/fulfillment-service/internal/cmd/cli/label"
"github.com/osac-project/fulfillment-service/internal/cmd/cli/login"
"github.com/osac-project/fulfillment-service/internal/cmd/cli/logout"
"github.com/osac-project/fulfillment-service/internal/cmd/cli/tenant"
"github.com/osac-project/fulfillment-service/internal/cmd/cli/version"
"github.com/osac-project/fulfillment-service/internal/config"
"github.com/osac-project/fulfillment-service/internal/logging"
Expand Down Expand Up @@ -85,6 +86,12 @@ func Root() (result *cobra.Command, err error) {
defaultCacheDir,
cacheFlagHelp,
)
flags.StringVar(
&runner.args.tenant,
tenantFlag,
"",
tenantFlagHelp,
)

// Add commands:
result.AddCommand(annotate.Cmd())
Expand All @@ -97,6 +104,7 @@ func Root() (result *cobra.Command, err error) {
result.AddCommand(label.Cmd())
result.AddCommand(login.Cmd())
result.AddCommand(logout.Cmd())
result.AddCommand(tenant.Cmd())
result.AddCommand(version.Cmd())

// Configure the root command, and therefore all its subcommands, to use Markdown for their help output:
Expand All @@ -110,6 +118,7 @@ type runnerContext struct {
args struct {
configDir string
cacheDir string
tenant string
}
}

Expand Down Expand Up @@ -197,11 +206,21 @@ func (c *runnerContext) persistentPreRun(cmd *cobra.Command, args []string) erro
return fmt.Errorf("failed to create console: %w", err)
}

// Replace the default context with one that contains the logger, the settings, and the console:
// Resolve the effective tenant: flag takes precedence over saved setting.
tenant := settings.Tenant()
if flags.Changed(tenantFlag) {
tenant = c.args.tenant
}

// Replace the default context with one that contains the logger, the settings, the console,
// and the resolved tenant:
ctx := cmd.Context()
ctx = logging.LoggerIntoContext(ctx, logger)
ctx = config.SettingsIntoContext(ctx, settings)
ctx = terminal.ConsoleIntoContext(ctx, console)
if tenant != "" {
ctx = config.TenantIntoContext(ctx, tenant)
}
cmd.SetContext(ctx)

return nil
Expand All @@ -211,6 +230,7 @@ func (c *runnerContext) persistentPreRun(cmd *cobra.Command, args []string) erro
const (
configFlag = "config"
cacheFlag = "cache"
tenantFlag = "tenant"
)

// Names of the environment variables:
Expand All @@ -235,6 +255,12 @@ Secrets, such as tokens and passwords, are stored in the operating system keyrin
they are stored in a file named {{ bt }}secrets.json{{ bt }} inside this directory.
`

const tenantFlagHelp = `
_NAME_ - Scope operations to the specified tenant. When set, list operations automatically filter by tenant,
and create operations populate {{ bt }}metadata.tenant{{ bt }} on new objects. If a current tenant has been
saved with {{ bt }}{{ binary }} tenant <name>{{ bt }}, the flag takes precedence.
`

const cacheFlagHelp = `
_DIRECTORY_ - Directory where cache and log files are stored. Can also be set with the {{ bt }}OSAC_CACHE{{ bt }}
environment variable. If both are provided, the flag takes precedence.
Expand Down
1 change: 1 addition & 0 deletions internal/cmd/cli/tenant/templates/current_tenant.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Current tenant: {{ .Tenant }}
14 changes: 14 additions & 0 deletions internal/cmd/cli/tenant/templates/multiple_matches.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Name '{{ .Ref }}' is ambiguous.

{{ if lt (len .Matches) .Total }}
There are {{ .Total }} matching tenants, these are the first {{ len .Matches }}:
{{ else }}
There are {{ .Total }} matching tenants:
{{ end }}

{{ table .Matches }}

{{ $first := index .Matches 0 }}
Use the identifier instead of the name to avoid ambiguity:

{{ binary }} tenant {{ $first.GetId }}
5 changes: 5 additions & 0 deletions internal/cmd/cli/tenant/templates/no_matches.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Tenant '{{ .Ref }}' not found.

Use the 'get' command to list available tenants:

{{ binary }} get tenants
9 changes: 9 additions & 0 deletions internal/cmd/cli/tenant/templates/no_tenant.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
No tenant is currently set.

To list available tenants:

{{ binary }} get tenants

To set a tenant:

{{ binary }} tenant <name>
Comment on lines +5 to +9

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find tenant command Use string and registered resources to confirm help text.
fd -t f 'tenant_cmd.go' internal/cmd/cli | xargs rg -n 'Use:|set-tenant|--clear'
rg -n 'Use:\s*"tenants?' internal/cmd/cli

Repository: osac-project/fulfillment-service

Length of output: 350


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Map tenant-related CLI command definitions and help templates.
ast-grep outline internal/cmd/cli/tenant/tenant_cmd.go --view expanded || true
rg -n 'get tenants|tenant --clear|tenant \[FLAG\.\.\.\] \[NAME\]|Use:' internal/cmd/cli -g '!**/*_test.go'
fd -t f . internal/cmd/cli | sed -n '1,200p'

Repository: osac-project/fulfillment-service

Length of output: 15372


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '1,220p' internal/cmd/cli/get/get_cmd.go
printf '\n--- tenant cmd ---\n'
sed -n '1,280p' internal/cmd/cli/tenant/tenant_cmd.go

Repository: osac-project/fulfillment-service

Length of output: 11872


🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n '\bget tenants\b|\bget tenant\b|tenant templates/no_(tenant|matches)\.txt|Lookup\("tenant"\)|OBJECT \[ID\|NAME\]' internal/cmd/cli docs README.md

Repository: osac-project/fulfillment-service

Length of output: 505


Replace the stale tenant help example. {{ binary }} get tenants is not a valid command here; the command takes an optional positional name, so the example should use {{ binary }} tenant or {{ binary }} tenant my-tenant 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 `@internal/cmd/cli/tenant/templates/no_tenant.txt` around lines 5 - 9, The
tenant help template contains an outdated example command, since `{{ binary }}
get tenants` is not valid for this CLI flow. Update the example text in the
no-tenant template used by the tenant command help to show the correct
positional usage, such as `{{ binary }} tenant` or `{{ binary }} tenant
my-tenant`, and keep the surrounding help copy aligned with the `tenant` command
behavior.

1 change: 1 addition & 0 deletions internal/cmd/cli/tenant/templates/tenant_cleared.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Tenant cleared.
1 change: 1 addition & 0 deletions internal/cmd/cli/tenant/templates/tenant_set.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Tenant '{{ .Tenant }}' saved. It will be used as the default for subsequent commands.
Loading
Loading