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

feat: plugins as services #16852

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open

Conversation

Joibel
Copy link
Member

@Joibel Joibel commented Jan 12, 2024

This commit makes the repo server able to use cmp plugins via kubernetes services.

Closes #14132 - read that for details of the design

Some discussion points for this PR:

  • Plugin name: Currently determined by the port name in the service. One service can have many ports, and this feels somewhat useful, so I chose the port name. My guess is the correct thing to do is add another gRPC call, which could also return the parameters (future UI work could then expose them for those people who use it to create apps). We'd then query on first noticing and then poll every 30 seconds. I'd like feedback on whether this is the right approach and desired - if so I'll add it.
  • We cache the service list, but not the sidecar list. I'm assuming some plugins could take time to initialise, so may not have created a socket file in time for a cache at startup approach. It would be trivial to switch though.
  • SA Token + role + rolebindings in the repo server: I've added it as default mounted now because it makes service plugins just work. Happy not to do this though.
  • Namespace configuration for where to find services is via en environment variable. I didn't originally propose it, but I think it's the right approach now.
  • No tests written yet whilst we ascertain what we want.

Checklist:

  • Either (a) I've created an enhancement proposal and discussed it with the community, (b) this is a bug fix, or (c) this does not need to be in the release notes.
  • The title of the PR states what changed and the related issues number (used for the release note).
  • The title of the PR conforms to the Toolchain Guide
  • I've included "Closes [ISSUE #]" or "Fixes [ISSUE #]" in the description to automatically close the associated issue.
  • I've updated both the CLI and UI to expose my feature, or I plan to submit a second PR with them.
  • Does this PR require documentation updates?
  • I've updated documentation as required by this PR.
  • I have signed off all my commits as required by DCO
  • I have written unit and/or e2e tests for my change. PRs without these are unlikely to be merged.
  • My build is green (troubleshooting builds).
  • My new feature complies with the feature status guidelines.
  • I have added a brief description of why this PR is necessary and/or what this PR solves.
  • Optional. My organization is added to USERS.md.
  • Optional. For bug fixes, I've indicated what older releases this fix should be cherry-picked into (this may or may not happen depending on risk/complexity).

@Joibel Joibel requested review from a team as code owners January 12, 2024 16:00
Copy link
Member

@tico24 tico24 left a comment

Choose a reason for hiding this comment

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

Some docs change requests

docs/operator-manual/config-management-plugins.md Outdated Show resolved Hide resolved
docs/operator-manual/config-management-plugins.md Outdated Show resolved Hide resolved
docs/operator-manual/config-management-plugins.md Outdated Show resolved Hide resolved
docs/operator-manual/config-management-plugins.md Outdated Show resolved Hide resolved
docs/operator-manual/config-management-plugins.md Outdated Show resolved Hide resolved
docs/operator-manual/config-management-plugins.md Outdated Show resolved Hide resolved
docs/operator-manual/config-management-plugins.md Outdated Show resolved Hide resolved
docs/operator-manual/config-management-plugins.md Outdated Show resolved Hide resolved
docs/operator-manual/config-management-plugins.md Outdated Show resolved Hide resolved
docs/operator-manual/config-management-plugins.md Outdated Show resolved Hide resolved
Copy link
Member

@tico24 tico24 left a comment

Choose a reason for hiding this comment

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

minor nit

docs/operator-manual/config-management-plugins.md Outdated Show resolved Hide resolved
Copy link

codecov bot commented Jan 15, 2024

Codecov Report

Attention: Patch coverage is 21.64502% with 181 lines in your changes are missing coverage. Please review.

Project coverage is 49.10%. Comparing base (397063f) to head (df2caf8).
Report is 106 commits behind head on master.

❗ Current head df2caf8 differs from pull request most recent head 42761cf. Consider uploading reports for the commit 42761cf to get more accurate results

Files Patch % Lines
util/app/discovery/services.go 0.00% 81 Missing ⚠️
util/app/discovery/plugin.go 32.91% 52 Missing and 1 partial ⚠️
util/app/discovery/discovery.go 27.90% 31 Missing ⚠️
reposerver/repository/repository.go 38.88% 11 Missing ⚠️
cmd/argocd/commands/app.go 0.00% 5 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master   #16852      +/-   ##
==========================================
- Coverage   49.21%   49.10%   -0.12%     
==========================================
  Files         274      276       +2     
  Lines       48111    48276     +165     
==========================================
+ Hits        23677    23704      +27     
- Misses      22090    22227     +137     
- Partials     2344     2345       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@Joibel Joibel marked this pull request as draft January 15, 2024 15:20
@Joibel Joibel force-pushed the plugins-as-services branch 5 times, most recently from 782c4e7 to 4709953 Compare January 16, 2024 09:51
@Joibel Joibel marked this pull request as ready for review January 16, 2024 11:36
docs/operator-manual/config-management-plugins.md Outdated Show resolved Hide resolved
docs/operator-manual/config-management-plugins.md Outdated Show resolved Hide resolved
docs/operator-manual/config-management-plugins.md Outdated Show resolved Hide resolved
docs/operator-manual/config-management-plugins.md Outdated Show resolved Hide resolved
docs/operator-manual/config-management-plugins.md Outdated Show resolved Hide resolved
docs/operator-manual/config-management-plugins.md Outdated Show resolved Hide resolved
util/app/discovery/discovery.go Outdated Show resolved Hide resolved
util/app/discovery/discovery.go Outdated Show resolved Hide resolved
util/app/discovery/plugin.go Outdated Show resolved Hide resolved
util/app/discovery/services.go Outdated Show resolved Hide resolved
@Joibel Joibel force-pushed the plugins-as-services branch from df2caf8 to a8b8175 Compare January 22, 2024 10:35
Copy link
Member

@crenshaw-dev crenshaw-dev left a comment

Choose a reason for hiding this comment

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

Overall, I'm liking the ideas.

I do think we should implement some form of auth on v1. Other unauth'ed components are a problem, and it's difficult to retroactively add that.

I also think some of the new files could use more test coverage.

But generally, looking good!

@Joibel
Copy link
Member Author

Joibel commented Feb 26, 2024

How about this thing from above:
"Plugin name: Currently determined by the port name in the service. One service can have many ports, and this feels somewhat useful, so I chose the port name. My guess is the correct thing to do is add another gRPC call, which could also return the parameters (future UI work could then expose them for those people who use it to create apps). We'd then query on first noticing and then poll every 30 seconds. I'd like feedback on whether this is the right approach and desired - if so I'll add it."

Do you have ideas on how you'd like auth to work?

@crenshaw-dev
Copy link
Member

Might have to hop on a call to 100% understand the port issue. Gotta focus on ArgoCon stuff for now.

re: auth - I think we should probably ask the user to generate a Secret and mount it to the FS of both the repo-server and the plugins. The plugin server would require that the password be present in gRPC call metadata for every call.

@leoluz leoluz added the component:cmp Config Management Plugin related issues label Feb 28, 2024
@Joibel Joibel force-pushed the plugins-as-services branch from 42761cf to 7dfbd61 Compare July 9, 2024 15:10
Joibel and others added 4 commits July 9, 2024 16:13
This commit makes the repo server able to use cmp plugins via kubernetes
services.

It implements argoproj#14132 - read that for details

Signed-off-by: Alan Clucas <alan@clucas.org>
Co-authored-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
Signed-off-by: Alan Clucas <alan@clucas.org>
Signed-off-by: Alan Clucas <alan@clucas.org>
Signed-off-by: Alan Clucas <alan@clucas.org>
@Joibel Joibel force-pushed the plugins-as-services branch from 7dfbd61 to 504d406 Compare July 9, 2024 15:13
@Joibel
Copy link
Member Author

Joibel commented Jul 11, 2024

This is ready for re-review. The CI license check is failing, but it is for everything these days.

path := fmt.Sprintf("%s/%s", strings.TrimRight(a.filePath, "/"), common.PluginAuthSecretName)
content, err := os.ReadFile(path)
if err != nil {
log.Errorf("No authentication secret present at %s", path)
Copy link
Member

Choose a reason for hiding this comment

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

As someone who spends an inordinate amount of time reading error messages that involve lousy inputs (especially leading/trailing whitespace), I'd like to encourage people to consistently wrap string variables in a quotation character.

Suggested change
log.Errorf("No authentication secret present at %s", path)
log.Errorf("No authentication secret present at '%s'", path)

Note: ideally argocd would be consistent about whether it's using ", ', or "`", but it isn't right now, so if you pick the one that is used the most or by things closest to this code, that'd be great.

@@ -0,0 +1 @@
tests/unreadable
Copy link
Member

Choose a reason for hiding this comment

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

Can you add a newline at EOF? (I'm not sure how to get github to let me suggest this...)

if err != nil {
log.Errorf("Unable to connect to config management plugin service with address %s", address)
log.Errorf("Unable to connect to config management plugin with address %s (type %s)", c.address, c.clientType.String())
Copy link
Member

Choose a reason for hiding this comment

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

If address has a risk of having garbage characters, then quotes would be good. I'm assuming that type is a relatively constrained thing and thus shouldn't need them.

return &clientSet{address: address, secretPath: secretPath, clientType: clientType}
}

// wrappedStream wraps around the embedded grpc.ClientStream, and intercepts the RecvMsg and
Copy link
Member

Choose a reason for hiding this comment

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

Unless there's a stylistic thing for the double space here...

Suggested change
// wrappedStream wraps around the embedded grpc.ClientStream, and intercepts the RecvMsg and
// wrappedStream wraps around the embedded grpc.ClientStream, and intercepts the RecvMsg and

func (c *clientSet) readAuthSecret(root string) (string, error) {
tryPath := c.secretPath
for {
path := fmt.Sprintf(filepath.Join(root, tryPath, common.PluginAuthSecretName))
Copy link
Member

Choose a reason for hiding this comment

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

This should make the linter happy:

Suggested change
path := fmt.Sprintf(filepath.Join(root, tryPath, common.PluginAuthSecretName))
path := filepath.Join(root, tryPath, common.PluginAuthSecretName)

The alternative would be:

		path := fmt.Sprintf("%s", filepath.Join(root, tryPath, common.PluginAuthSecretName))

The current code is risky in C languages if someone could construct root, tryPath, or common.PluginAuthSecretName to include %... (I expect go might not count as a C language here, but it's good practice to avoid risky style...)

}
tryPath = filepath.Dir(tryPath)
}
return ``, status.Errorf(codes.Unauthenticated, "No authentication secret present at %s or parents", filepath.Join(root, c.secretPath))
Copy link
Member

Choose a reason for hiding this comment

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

I'd probably want quotes around %s.

I'm not sure what parents is in context. (It's also possible it needs a possessive ' marker.)

// PluginConfigFileName is the Plugin Config File is a ConfigManagementPlugin manifest located inside the plugin container
PluginConfigFileName = "plugin.yaml"
// PluginAuthSecretName is the name of the authentication secret located inside the plugin container
PluginAuthSecretName = "secret"
// PluginAuthTokenHeader is the name of the header to be used for auth. It must be lower case.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// PluginAuthTokenHeader is the name of the header to be used for auth. It must be lower case.
// PluginAuthTokenHeader is the name of the header to be used for auth. It must be lowercase.


!!! Ensure that:
1. The argocd-repo-server deployment has `automountServiceAccountToken: true`
2. The argocd-repo-server's service account has a role binding allowing `get`, `list` and `watch` on services.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
2. The argocd-repo-server's service account has a role binding allowing `get`, `list` and `watch` on services.
2. The argocd-repo-server's service account has a role binding allowing `get`, `list` and `watch` on services.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component:cmp Config Management Plugin related issues
Projects
Status: Ready for final review
Development

Successfully merging this pull request may close these issues.

proposal: Plugins as services
6 participants