Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: add Warning message on Version mismatch between CLI and Server. fixes #9212 #11909

Closed
wants to merge 1 commit into from

Conversation

fhochleitner
Copy link
Contributor

add Warning message on Version mismatch between CLI and Server.
implemented a check whether argocli and arger-server version are based on the same git-tag and print a warning when versions are mismatched.

Fixes #9212

Motivation

Wanted to start contributing and found an issue that seemed to be a nice start for this journey

Modifications

added function to compare cli and server version and prints a warning in case versions do not match. function fails with warning messages if it cannot contact server as it should not break everything in case of an error.

Verification

built cli and tested it against argo-workflows running on a cluster. happy to implement some e2e tests if required but would need some pointers.

@fhochleitner fhochleitner marked this pull request as draft September 30, 2023 06:52
@fhochleitner fhochleitner changed the title WIP fix: add Warning message on Version mismatch between CLI and Server. fixes #9212 fix: add Warning message on Version mismatch between CLI and Server. fixes #9212 Sep 30, 2023
@fhochleitner fhochleitner marked this pull request as ready for review October 3, 2023 06:37
@fhochleitner
Copy link
Contributor Author

I've placed the version check into the root command so it get's executed and prints the warning no matter command the user actually uses and gets notified in case. but I'm not sure whether that's the right as it does execute a few network calls for all commands. happy to implement changes if you have a way to implement this in a smarter way

@agilgur5
Copy link
Member

agilgur5 commented Oct 5, 2023

Wanted to start contributing and found an issue that seemed to be a nice start for this journey

Great start, thanks!

happy to implement some e2e tests if required but would need some pointers.

There are some unit tests for the CLI already that you can use as an example. Same directory, *_test.go files

but I'm not sure whether that's the right as it does execute a few network calls for all commands. happy to implement changes if you have a way to implement this in a smarter way

If we wanted to optimize this specific call, we could run it async (e.g. in a goroutine) so it doesn't block other commands.
To have less network requests, one common way is to pull the version out of a header or something from an existing network call.

cmd/argo/commands/root.go Outdated Show resolved Hide resolved

// printVersionMismatchWarning logs a warning if the CLI version does not match the server version
func printVersionMismatchWarning(command *cobra.Command) {
// if ARGO_SERVER isn't set there's no need to compare server and cli version
Copy link
Member

@agilgur5 agilgur5 Oct 5, 2023

Choose a reason for hiding this comment

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

I'm not sure that this is necessarily accurate. Any usage of the CLI could have unexpected results if there is a version mismatch. For example, through the k8s API, the CLI could be using an outdated spec

Copy link
Contributor Author

Choose a reason for hiding this comment

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

you're right. a check would definitely be useful in this case as well. do you know whether there's a way to get a version that's comparable with the cli version directly via api access? I haven't been able to find one but then again I am not very familiar with the codebase yet.

Copy link

Choose a reason for hiding this comment

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

While I agree with:

Any usage of the CLI could have unexpected results if there is a version mismatch.

Even the version command does not check the server version if ARGO_SERVER is not defined. I'm assuming is not that simple to determine the version in that case.

https://github.com/argoproj/argo-workflows/blob/main/cmd/argo/commands/version.go#L23

Copy link
Member

@agilgur5 agilgur5 Jul 6, 2024

Choose a reason for hiding this comment

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

My comment was about the "there's no need to compare" comment. That is inaccurate.
You may not be able to retrieve it without ARGO_SERVER set, but it is nonetheless inaccurate to say "there is no need compare". It would be more apt to say "you can't compare". But the comment is a bit redundant at that point

Copy link

@driv driv Jul 6, 2024

Choose a reason for hiding this comment

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

Great, I agree.

Comment on lines +163 to +165
if serverVersion.GitTag != argo.GetVersion().GitTag {
log.Warnf("CLI version (%s) does not match server version (%s). This can lead to unexpected behavior.", argo.GetVersion().GitTag, serverVersion.GitTag)
}
Copy link
Member

Choose a reason for hiding this comment

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

I think it might be a better idea if you separated out the logic that checks for a mismatch from the code that presents this information to the user.

Only saying this because we could make this a bit more strict then, we could fail on a version mismatch and have a flag to force any action to be performed regardless.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ah sorry for not having able to continue working on this PR. work and private life got quite busy as of late.
I'm not sure this will change a lot in the coming months, but I do think that's a great idea @isubasinghe

Copy link
Member

Choose a reason for hiding this comment

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

No worries, take your time!

@juliev0 juliev0 added problem/stale This has not had a response in some time problem/more information needed Not enough information has been provide to diagnose this issue. labels Jun 28, 2024
@github-actions github-actions bot removed problem/stale This has not had a response in some time problem/more information needed Not enough information has been provide to diagnose this issue. labels Jun 30, 2024
@juliev0 juliev0 added the problem/more information needed Not enough information has been provide to diagnose this issue. label Jul 3, 2024
@driv
Copy link

driv commented Jul 6, 2024

Since this is marked as stale and relatively simple, I can take a look.

This comment was marked as resolved.

@github-actions github-actions bot added the problem/stale This has not had a response in some time label Jul 21, 2024

This comment was marked as resolved.

@github-actions github-actions bot closed this Aug 4, 2024
MasonM added a commit to MasonM/argo-workflows that referenced this pull request Sep 20, 2024
…ixes argoproj#9212

This adds a warning message to the CLI when it detects a mismatch
between the client and server versions. There was another PR
(argoproj#11909) for this
implemented it by making a blocking API call to `/api/v1/version` in a
`PersistentPreRun` hook. This PR takes a different approach: have the
server send the version in a new header called `argo-version`, which the
client will detect and extract. There's several advantages to this
approach:
1. Negligible performance impact, since no additional requests are
   needed.
2. Warning is only shown when the command would normally send an API
   request, so we
3. Can be useful for bug triaging, since the header can be seen in
   `curl` output.

Exposing the version information has security implictions, since it
could be used by attackers to identify vulnerable Argo servers. To
mitigate that, the header is not sent on 401 errors. Of course, if
a user is exposing their Argo server to the internet without
authentication, then an attacker could see this header, but then they've
got bigger problems (and an attacker could just call `/api/v1/version`).

This is implemented on the client and server side using [grpc-go
interceptors](https://github.com/grpc/grpc-go/blob/master/examples/features/interceptor/README.md).
On the server side, there's interceptors to set the version header in
the response. On the client side, there's an interceptor to check the
response for the header and stash it in a global variable (which
is obviously not ideal, but I couldn't think of a better way to handle
that).

Testing process:
1. Manually changed the version to `v9.99`: https://github.com/argoproj/argo-workflows/blob/ce7f9bfb9b45f009b3e85fabe5e6410de23c7c5f/Makefile#L95
2. Ran `make cli && cp dist/argo argo2`
3. Ran `make start API=true`
4. Ran `ARGO_SECURE=false ARGO_TOKEN="Bearer $(kubectl get secret argo-server.service-account-token -o=jsonpath='{.data.token}' | base64 --decode)" ARGO_SERVER=localhost:2746 ./dist/argo2 list`

Output:
```
No workflows found
WARN[2024-09-20T18:03:26.116Z] CLI version (v9.99+303bcce.dirty) does not match server version (latest+303bcce.dirty). This can lead to unexpected behavior.
```
MasonM added a commit to MasonM/argo-workflows that referenced this pull request Sep 20, 2024
…ixes argoproj#9212

This adds a warning message to the CLI when it detects a mismatch
between the client and server versions. There was another PR
(argoproj#11909) for this
implemented it by making a blocking API call to `/api/v1/version` in a
`PersistentPreRun` hook. This PR takes a different approach: have the
server send the version in a new header called `argo-version`, which the
client will detect and extract. There's several advantages to this
approach:
1. Negligible performance impact, since no additional requests are
   needed.
2. Warning is only shown when the command would normally send an API
   request.
3. Can be useful for bug triaging, since the header can be seen in
   `curl` output.

Exposing the version information has security implictions, since it
could be used by attackers to identify vulnerable Argo servers. To
mitigate that, the header is not sent on 401 errors. Of course, if
a user is exposing their Argo server to the internet without
authentication, then an attacker could see this header, but then they've
got bigger problems (and an attacker could just call `/api/v1/version`).

This is implemented on the client and server side using [grpc-go
interceptors](https://github.com/grpc/grpc-go/blob/master/examples/features/interceptor/README.md).
On the server side, there's interceptors to set the version header in
the response. On the client side, there's an interceptor to check the
response for the header and stash it in a global variable (which
is obviously not ideal, but I couldn't think of a better way to handle
that).

Testing process:
1. Manually changed the version to `v9.99`: https://github.com/argoproj/argo-workflows/blob/ce7f9bfb9b45f009b3e85fabe5e6410de23c7c5f/Makefile#L95
2. Ran `make cli && cp dist/argo argo2`
3. Ran `make start API=true`
4. Ran `ARGO_SECURE=false ARGO_TOKEN="Bearer $(kubectl get secret argo-server.service-account-token -o=jsonpath='{.data.token}' | base64 --decode)" ARGO_SERVER=localhost:2746 ./dist/argo2 list`

Output:
```
No workflows found
WARN[2024-09-20T18:03:26.116Z] CLI version (v9.99+303bcce.dirty) does not match server version (latest+303bcce.dirty). This can lead to unexpected behavior.
```

Signed-off-by: Mason Malone <[email protected]>
MasonM added a commit to MasonM/argo-workflows that referenced this pull request Sep 20, 2024
…ixes argoproj#9212

This adds a warning message to the CLI when it detects a mismatch
between the client and server versions. There was another PR
(argoproj#11909) for this
implemented it by making a blocking API call to `/api/v1/version` in a
`PersistentPreRun` hook. This PR takes a different approach: have the
server send the version in a new header called `argo-version`, which the
client will detect and extract. There's several advantages to this
approach:
1. Negligible performance impact, since no additional requests are
   needed.
2. Warning is only shown when the command would normally send an API
   request.
3. Can be useful for bug triaging, since the header can be seen in
   `curl` output.

Exposing the version information has security implictions, since it
could be used by attackers to identify vulnerable Argo servers. To
mitigate that, the header is not sent on 401 errors. Of course, if
a user is exposing their Argo server to the internet without
authentication, then an attacker could see this header, but then they've
got bigger problems (and an attacker could just call `/api/v1/version`).

This is implemented on the client and server side using [grpc-go
interceptors](https://github.com/grpc/grpc-go/blob/master/examples/features/interceptor/README.md).
On the server side, there's interceptors to set the version header in
the response. On the client side, there's an interceptor to check the
response for the header and stash it in a global variable (which
is obviously not ideal, but I couldn't think of a better way to handle
that).

Testing process:
1. Manually changed the version to `v9.99`: https://github.com/argoproj/argo-workflows/blob/ce7f9bfb9b45f009b3e85fabe5e6410de23c7c5f/Makefile#L95
2. Ran `make cli && cp dist/argo argo2`
3. Ran `make start API=true`
4. Ran `ARGO_SECURE=false ARGO_TOKEN="Bearer $(kubectl get secret argo-server.service-account-token -o=jsonpath='{.data.token}' | base64 --decode)" ARGO_SERVER=localhost:2746 ./dist/argo2 list`

Output:
```
No workflows found
WARN[2024-09-20T18:03:26.116Z] CLI version (v9.99+303bcce.dirty) does not match server version (latest+303bcce.dirty). This can lead to unexpected behavior.
```

Signed-off-by: Mason Malone <[email protected]>
@agilgur5 agilgur5 removed problem/stale This has not had a response in some time problem/more information needed Not enough information has been provide to diagnose this issue. labels Sep 21, 2024
@agilgur5
Copy link
Member

Superseded by #13635

@agilgur5 agilgur5 added the solution/superseded This PR or issue has been superseded by another one (slightly different from a duplicate) label Sep 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/cli The `argo` CLI solution/superseded This PR or issue has been superseded by another one (slightly different from a duplicate)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

CLI: warn when CLI version is outdated compared to Server
5 participants