Skip to content

Config Management via UAP #1919

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

Merged
merged 31 commits into from
Apr 1, 2025
Merged

Config Management via UAP #1919

merged 31 commits into from
Apr 1, 2025

Conversation

XuechunHou
Copy link
Contributor

@XuechunHou XuechunHou commented Mar 28, 2025

Description

The Ops Agent UAP Plugin can receive custom configurations from UAP via its Start() endpoint in two formats: string and proto struct.

The UAP front end allows users to upload a config.yaml file, which is converted to a proto struct at the front end. The UAP backend sends it to the corresponding plugin.

Alternatively, users can enter a string blob, which is passed directly to the Plugin's Start endpoint as is.

The UAP Plugin handles both configuration formats. When a string config is received, the plugin directly writes it to the config.yaml file, delegating validation to the config generator.

When a proto struct config is received, the plugin converts it back to YAML format before writing it to the config.yaml file. Again, the config validation is performed by the conf generator.

Related issue

b/406576144

How has this been tested?

Unit tests have been added for both Linux and Windows. These tests verify that when the Plugin receives no configuration from UAP, the config.yaml file remains unchanged.

When the Plugin receives a non-empty configuration from UAP, it overwrites the config.yaml file. Furthermore, if the input configuration is a valid Ops Agent configuration, the output written to the file should also be valid.

Integration tests have also been added, but currently only for Linux. This is because the StartRequest needs to be stringified during testing, and Windows requires different escaping mechanisms.

Checklist:

  • Unit tests
    • Unit tests do not apply.
    • Unit tests have been added/modified and passed for this PR.
  • Integration tests
    • Integration tests do not apply.
    • Integration tests have been added/modified and passed for this PR.
  • Documentation
    • This PR introduces no user visible changes.
    • This PR introduces user visible changes and the corresponding documentation change has been made.
  • Minor version bump
    • This PR introduces no new features.
    • This PR introduces new features, and there is a separate PR to bump the minor version since the last release already.
    • This PR bumps the version.

@XuechunHou XuechunHou requested a review from jinghan-ma March 31, 2025 21:53
@XuechunHou XuechunHou self-assigned this Mar 31, 2025
Dockerfile Outdated
@@ -176,6 +176,7 @@ RUN ./pkg/rpm/build.sh
COPY cmd/ops_agent_uap_plugin cmd/ops_agent_uap_plugin
COPY ./builds/ops_agent_plugin.sh .
RUN ./ops_agent_plugin.sh /work/cache/
RUN source VERSION && echo $PKG_VERSION > /work/cache/OPS_AGENT_VERSION

Choose a reason for hiding this comment

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

Should we put this in ./ops_agent_plugin.sh? This way we don't have to repeat it for each image, and also there's fewer Docker build stages, so fewer layers and faster build time.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

switch req.GetServiceConfig().(type) {
case *pb.StartRequest_StringConfig:
customConfig = []byte(req.GetStringConfig())
case *pb.StartRequest_StructConfig:

Choose a reason for hiding this comment

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

If a user inputs a custom yaml and it's able to parse into a StructConfig, would the StringConfig also be sent, or only the parsed version?

If both are sent, wouldn't this case never trigger?

Choose a reason for hiding this comment

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

Also, do we even want to use the parsed config?

Since we simply write the config to a file and let the Ops Agent handle it, do we need to check for proper yaml at this stage?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

https://source.corp.google.com/piper///depot/google3/third_party/guest_agent/dev/internal/plugin/proto/plugin_comm.proto;l=53 service_config is a oneof field, so either string_config or struct_config is sent per StartRequest, never both.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Also, do we even want to use the parsed config?

Since we simply write the config to a file and let the Ops Agent handle it, do we need to check for proper yaml at this stage?

"Also, do we even want to use the parsed config?" If the FE allows both, we will have to handle both.

struct_config is populated when users upload a config.yaml file at the FE, it will be parsed, validated and converted to a struct proto at the FE before us receiving it.

string_config is populated when users paste a chunk of string at the FE, the string will be forwarded to us as is without any validation.

I am not doing any validation at this stage really, I am just converting the struct proto back to a yaml and writes it to config.yaml file. Whether it's a valid Ops Agent config yaml is left to the conf generator...

@XuechunHou XuechunHou merged commit 9b90da6 into master Apr 1, 2025
70 of 73 checks passed
@XuechunHou XuechunHou deleted the config-management branch April 1, 2025 23:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants