nats-io / natscli

The NATS Command Line Interface
Apache License 2.0
510 stars 99 forks source link

editing streams shows wrong diff output #1171

Closed marcm-ml closed 1 month ago

marcm-ml commented 1 month ago

Observed behavior

When editing a stream, it shows config items to be changed which have not been changed. Furthermore, after editing, these supposedly changes are not applied to the actual stream.

Expected behavior

show actual changes

Server and client version

cli: 0.1.5 server: 2.10.21

Host environment

macOS-arm with docker but also on eks kubernetes cluster

Steps to reproduce

Start nats-server

create bare minimum stream config file:

{
  "name": "TEST",
  "num_replicas": 1
}

create stream: nats stream add --config config.json --json gives

{
  "config": {
    "name": "TEST",
    "subjects": [
      "TEST"
    ],
    "retention": "limits",
    "max_consumers": -1,
    "max_msgs_per_subject": -1,
    "max_msgs": -1,
    "max_bytes": -1,
    "max_age": 0,
    "max_msg_size": -1,
    "storage": "file",
    "discard": "old",
    "num_replicas": 1,
    "duplicate_window": 120000000000,
    "sealed": false,
    "deny_delete": false,
    "deny_purge": false,
    "allow_rollup_hdrs": false,
    "allow_direct": false,
    "mirror_direct": false,
    "consumer_limits": {}
  },
  "created": "2024-10-09T15:08:08.074412834Z",
  "state": {
    "messages": 0,
    "bytes": 0,
    "first_seq": 0,
    "first_ts": "0001-01-01T00:00:00Z",
    "last_seq": 0,
    "last_ts": "0001-01-01T00:00:00Z",
    "consumer_count": 0
  },
  "ts": "2024-10-09T15:08:08.075448292Z"
}

edit stream: nats stream edit --config config.json --force --json which should not show any changes but outputs for me:

Differences (-old +new):
  api.StreamConfig{
        Name:         "TEST",
        Description:  "",
-       Subjects:     []string(Inverse(Sort, []string{"TEST"})),
+       Subjects:     []string(Inverse(Sort, []string(nil))),
        Retention:    s"Limits",
-       MaxConsumers: -1,
+       MaxConsumers: 0,
-       MaxMsgsPer:   -1,
+       MaxMsgsPer:   0,
-       MaxMsgs:      -1,
+       MaxMsgs:      0,
-       MaxBytes:     -1,
+       MaxBytes:     0,
        MaxAge:       s"0s",
-       MaxMsgSize:   -1,
+       MaxMsgSize:   0,
        Storage:      s"File",
        Discard:      s"Old",
        Replicas:     1,
        NoAck:        false,
        Template:     "",
-       Duplicates:   s"2m0s",
+       Duplicates:   s"0s",
        Placement:    nil,
        Mirror:       nil,
        ... // 14 identical fields
  }
{
  "config": {
    "name": "TEST",
    "subjects": [
      "TEST"
    ],
    "retention": "limits",
    "max_consumers": -1,
    "max_msgs_per_subject": -1,
    "max_msgs": -1,
    "max_bytes": -1,
    "max_age": 0,
    "max_msg_size": -1,
    "storage": "file",
    "discard": "old",
    "num_replicas": 1,
    "duplicate_window": 120000000000,
    "sealed": false,
    "deny_delete": false,
    "deny_purge": false,
    "allow_rollup_hdrs": false,
    "allow_direct": false,
    "mirror_direct": false,
    "consumer_limits": {}
  },
  "created": "2024-10-09T15:01:53.230786716Z",
  "state": {
    "messages": 0,
    "bytes": 0,
    "first_seq": 0,
    "first_ts": "0001-01-01T00:00:00Z",
    "last_seq": 0,
    "last_ts": "0001-01-01T00:00:00Z",
    "consumer_count": 0
  },
  "cluster": {
    "leader": "NAH35DMLCDN7HDPLHLEYBPVXPMB256UFGN7LBXI4RCQNYNNLLX6EWX5M"
  },
  "ts": "2024-10-09T15:06:03.922308513Z"
}
ripienaar commented 1 month ago

unfortunately the server does a lot of changes to the config you provide, you need to give full configs its unavoidable

marcm-ml commented 1 month ago

I am not sure if I understand the output then. To me it seems that omitted values from a config file have different default values in the add and edit command, hence the diff output. Also when I look at the config of the stream after editing, it’s still the same config, e.g. max_consumer is still -1 and not 0 which the edit command seem to suggest. So the behavior is as I would expected where config file is merged with the current config of the stream on the server, but the output of the edit command is just wrong?

ripienaar commented 1 month ago

When a json file doesn’t have a value it’s zero. But we initialise many to -1 for infinite or unset.

But when you edit a stream the config given by you isn’t aware of this change and so it all differs.

The config given to edit isn’t seen as a patch. It rather as the full new config. And yours is missing all the fields we treated as default -1 and so you see this.

marcm-ml commented 1 month ago

Ah okay, I think I got it. Thanks for clarifying