Skip to content

Commit db1b1b7

Browse files
fix: allow user to only set one field for ng or cz (#211) (#213)
Signed-off-by: Amber Xue <ambermingxin@nvidia.com> Signed-off-by: Jingxiang Zhang <jingzhang@nvidia.com> Co-authored-by: ambermingxin <ambermingxin@nvidia.com>
1 parent c0100c6 commit db1b1b7

8 files changed

Lines changed: 82 additions & 61 deletions

File tree

cmd/fleetint/enroll.go

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,6 @@ func enrollCommand(cliContext *cli.Context) error {
9696
if err != nil {
9797
return err
9898
}
99-
if err := validateReservedPairMetadata(nodeGroup, computeZone); err != nil {
100-
return err
101-
}
10299
metadata := &enrollment.EnrollMetadata{
103100
NodeGroup: nodeGroup,
104101
ComputeZone: computeZone,
@@ -159,20 +156,3 @@ func validatedOptionalMetadataFlagValue(cliContext *cli.Context, name, fieldName
159156
}
160157
return &value, nil
161158
}
162-
163-
func validateReservedPairMetadata(nodeGroup, computeZone *string) error {
164-
nodeGroupSet := nodeGroup != nil
165-
computeZoneSet := computeZone != nil
166-
167-
if !nodeGroupSet && !computeZoneSet {
168-
return nil
169-
}
170-
if nodeGroupSet && computeZoneSet {
171-
nodeGroupEmpty := *nodeGroup == ""
172-
computeZoneEmpty := *computeZone == ""
173-
if nodeGroupEmpty == computeZoneEmpty {
174-
return nil
175-
}
176-
}
177-
return fmt.Errorf("--node-group and --compute-zone must be both omitted, both empty, or both non-empty")
178-
}

cmd/fleetint/enroll_test.go

Lines changed: 64 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -340,49 +340,83 @@ func TestEnrollCommandRejectsOverlongMetadataNames(t *testing.T) {
340340
require.ErrorContains(t, err, "Node group name must be 255 characters or fewer")
341341
}
342342

343-
func TestValidateReservedPairMetadata(t *testing.T) {
343+
func TestValidatedOptionalMetadataFlagValueSupportsIndependentReservedUpdates(t *testing.T) {
344344
strPtr := func(v string) *string { return &v }
345345
tests := []struct {
346-
name string
347-
nodeGroup *string
348-
computeZone *string
349-
wantErr bool
346+
name string
347+
nodeGroupArg *string
348+
computeZoneArg *string
349+
expectNodeGroup *string
350+
expectComputeZone *string
350351
}{
351-
{name: "both omitted", nodeGroup: nil, computeZone: nil, wantErr: false},
352-
{name: "both empty", nodeGroup: strPtr(""), computeZone: strPtr(""), wantErr: false},
353-
{name: "both non-empty", nodeGroup: strPtr("ng-a"), computeZone: strPtr("cz-a"), wantErr: false},
354-
{name: "node-group only", nodeGroup: strPtr("ng-a"), computeZone: nil, wantErr: true},
355-
{name: "compute-zone only", nodeGroup: nil, computeZone: strPtr("cz-a"), wantErr: true},
356-
{name: "node-group empty compute-zone non-empty", nodeGroup: strPtr(""), computeZone: strPtr("cz-a"), wantErr: true},
357-
{name: "node-group non-empty compute-zone empty", nodeGroup: strPtr("ng-a"), computeZone: strPtr(""), wantErr: true},
352+
{
353+
name: "clear compute-zone and set node-group",
354+
nodeGroupArg: strPtr("xx"),
355+
computeZoneArg: strPtr(""),
356+
expectNodeGroup: strPtr("xx"),
357+
expectComputeZone: strPtr(""),
358+
},
359+
{
360+
name: "set compute-zone and clear node-group",
361+
nodeGroupArg: strPtr(""),
362+
computeZoneArg: strPtr("xx"),
363+
expectNodeGroup: strPtr(""),
364+
expectComputeZone: strPtr("xx"),
365+
},
366+
{
367+
name: "set compute-zone and omit node-group",
368+
nodeGroupArg: nil,
369+
computeZoneArg: strPtr("xx"),
370+
expectNodeGroup: nil,
371+
expectComputeZone: strPtr("xx"),
372+
},
373+
{
374+
name: "set node-group and omit compute-zone",
375+
nodeGroupArg: strPtr("xx"),
376+
computeZoneArg: nil,
377+
expectNodeGroup: strPtr("xx"),
378+
expectComputeZone: nil,
379+
},
380+
{
381+
name: "clear compute-zone and omit node-group",
382+
nodeGroupArg: nil,
383+
computeZoneArg: strPtr(""),
384+
expectNodeGroup: nil,
385+
expectComputeZone: strPtr(""),
386+
},
387+
{
388+
name: "clear node-group and omit compute-zone",
389+
nodeGroupArg: strPtr(""),
390+
computeZoneArg: nil,
391+
expectNodeGroup: strPtr(""),
392+
expectComputeZone: nil,
393+
},
358394
}
359395

360396
for _, tc := range tests {
361397
t.Run(tc.name, func(t *testing.T) {
362-
err := validateReservedPairMetadata(tc.nodeGroup, tc.computeZone)
363-
if tc.wantErr {
364-
require.ErrorContains(t, err, "--node-group and --compute-zone must be both omitted, both empty, or both non-empty")
365-
return
398+
flagSet := flag.NewFlagSet("enroll", flag.ContinueOnError)
399+
flagSet.String("node-group", "", "")
400+
flagSet.String("compute-zone", "", "")
401+
if tc.nodeGroupArg != nil {
402+
require.NoError(t, flagSet.Set("node-group", *tc.nodeGroupArg))
366403
}
404+
if tc.computeZoneArg != nil {
405+
require.NoError(t, flagSet.Set("compute-zone", *tc.computeZoneArg))
406+
}
407+
cliContext := cli.NewContext(cli.NewApp(), flagSet, nil)
408+
409+
nodeGroup, err := validatedOptionalMetadataFlagValue(cliContext, "node-group", "Node group")
367410
require.NoError(t, err)
411+
computeZone, err := validatedOptionalMetadataFlagValue(cliContext, "compute-zone", "Compute zone")
412+
require.NoError(t, err)
413+
414+
assert.Equal(t, tc.expectNodeGroup, nodeGroup)
415+
assert.Equal(t, tc.expectComputeZone, computeZone)
368416
})
369417
}
370418
}
371419

372-
func TestEnrollCommandRejectsMixedReservedPairValues(t *testing.T) {
373-
app := App()
374-
app.Writer = &bytes.Buffer{}
375-
376-
err := app.Run([]string{
377-
"fleetint", "enroll",
378-
"--endpoint", "https://example.com",
379-
"--token", "token",
380-
"--node-group", "",
381-
"--compute-zone", "cz-a",
382-
})
383-
require.ErrorContains(t, err, "--node-group and --compute-zone must be both omitted, both empty, or both non-empty")
384-
}
385-
386420
func TestEnrollCommandRejectsReservedUnassignedName(t *testing.T) {
387421
app := App()
388422
app.Writer = &bytes.Buffer{}

deployments/helm/fleet-intelligence-agent/values.yaml

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,10 @@ enroll:
6161
tokenSecretName: ""
6262
tokenSecretKey: "token"
6363
tokenValue: ""
64-
# Optional enrollment metadata:
65-
# - omit key to preserve existing stored value
66-
# - set non-empty string to overwrite
67-
# - set empty string ("") to clear
68-
#
69-
# nodeGroup: "prod-a"
70-
# computeZone: "us-east-1c"
64+
# Optional enrollment metadata. Omit these keys to preserve stored values.
65+
# Set to "" explicitly to clear stored values.
66+
# nodeGroup: ""
67+
# computeZone: ""
7168

7269
ports:
7370
http: 15133

internal/agentstate/sqlite_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"testing"
2424
"time"
2525

26+
pkgmetadata "github.com/NVIDIA/fleet-intelligence-sdk/pkg/metadata"
2627
"github.com/NVIDIA/fleet-intelligence-sdk/pkg/sqlite"
2728
"github.com/stretchr/testify/require"
2829
)
@@ -84,6 +85,15 @@ func TestSQLiteStateRoundTrip(t *testing.T) {
8485
require.True(t, ok)
8586
require.Equal(t, "group-a", value)
8687

88+
stateFile, err := state.stateFileFn()
89+
require.NoError(t, err)
90+
db, err := sqlite.Open(stateFile, sqlite.WithReadOnly(true))
91+
require.NoError(t, err)
92+
defer db.Close()
93+
value, err = pkgmetadata.ReadMetadata(ctx, db, "node_group")
94+
require.NoError(t, err)
95+
require.Equal(t, "group-a", value)
96+
8797
value, ok, err = state.GetComputeZone(ctx)
8898
require.NoError(t, err)
8999
require.True(t, ok)

internal/agentstate/state.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const (
2525
MetadataKeyBackendBaseURL = "backend_base_url"
2626
MetadataKeySAKToken = "sak_token"
2727
MetadataKeyEnrolledAt = "enrolled_at"
28-
MetadataKeyNodeGroup = "nodegroup"
28+
MetadataKeyNodeGroup = "node_group"
2929
MetadataKeyComputeZone = "compute_zone"
3030
)
3131

internal/enrollment/enrollment.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ func storeConfigInMetadata(ctx context.Context, baseURL, jwtToken, sakToken stri
175175
}
176176
if metadata.NodeGroup != nil {
177177
if err := pkgmetadata.SetMetadata(ctx, dbRW, agentstate.MetadataKeyNodeGroup, *metadata.NodeGroup); err != nil {
178-
return fmt.Errorf("failed to set nodegroup: %w", err)
178+
return fmt.Errorf("failed to set node_group: %w", err)
179179
}
180180
}
181181
if metadata.ComputeZone != nil {

internal/exporter/exporter.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ func (e *healthExporter) populateOptionalResourceMetadata(ctx context.Context, d
196196

197197
nodeGroup, err := pkgmetadata.ReadMetadata(ctx, e.options.dbRO, agentstate.MetadataKeyNodeGroup)
198198
if err != nil {
199-
log.Logger.Debugw("nodegroup metadata not available for telemetry resource", "error", err)
199+
log.Logger.Debugw("node_group metadata not available for telemetry resource", "error", err)
200200
} else {
201201
data.NodeGroup = nodeGroup
202202
}

internal/inventory/sink/backend.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ func (s *backendSink) Export(ctx context.Context, snap *inventory.Snapshot) erro
8383
req := mapper.ToNodeUpsertRequest(snap)
8484
nodeGroup, ok, err := s.state.GetNodeGroup(ctx)
8585
if err != nil {
86-
log.Logger.Warnw("inventory export continuing without nodegroup metadata", "error", err)
86+
log.Logger.Warnw("inventory export continuing without node_group metadata", "error", err)
8787
} else if ok {
8888
req.NodeGroup = nodeGroup
8989
}

0 commit comments

Comments
 (0)