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

[juju] Add plugin option for Juju state reporting #3803

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

MichaelThamm
Copy link

@MichaelThamm MichaelThamm commented Oct 10, 2024

This change modifies the Juju plugin to optionally capture Juju state (controllers, models, applications, units) information. The capture assumes that juju is installed on the machine where sos is called, and that the juju user has superuser privilege to the current (or requested) controllers.

This option is disabled by default because, while the information can be very useful, the collection acts on the live Juju state.

Use the plugin with the feature:

  • sos report --only-plugin juju -k juju.juju-state=True

Run with a specific user (who has access to the controllers specified). This defaults to ubuntu:

  • -k juju.juju-user=super_admin

If necessary, you can filter by controllers or models with cluster options.

  • -k juju.controllers="controller_a controller_b"
  • -k juju.models="controller_a:model_x controller_b:model_y"

If nothing is supplied for either the controllers or models options, the report will include all state information for them respectively.


Please place an 'X' inside each '[]' to confirm you adhere to our Contributor Guidelines

  • Is the commit message split over multiple lines and hard-wrapped at 72 characters?
  • Is the subject and message clear and concise?
  • Does the subject start with [plugin_name] if submitting a plugin patch or a [section_name] if part of the core sosreport code?
  • Does the commit contain a Signed-off-by: First Lastname [email protected]?
  • Are any related Issues or existing PRs properly referenced via a Closes (Issue) or Resolved (PR) line?
  • Are all passwords or private data gathered by this PR obfuscated?
  • Add tests to ensure results are scrubbed / functioning

Copy link

Congratulations! One of the builds has completed. 🍾

You can install the built RPMs by following these steps:

  • sudo yum install -y dnf-plugins-core on RHEL 8
  • sudo dnf install -y dnf-plugins-core on Fedora
  • dnf copr enable packit/sosreport-sos-3803
  • And now you can install the packages.

Please note that the RPMs should be used only in a testing environment.

Copy link
Member

@arif-ali arif-ali left a comment

Choose a reason for hiding this comment

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

As well as turboturtle comments, can we also look at the flake/pylint issues as well is any updated PR

sos/report/plugins/juju.py Outdated Show resolved Hide resolved
sos/report/plugins/juju.py Outdated Show resolved Hide resolved
sos/report/plugins/juju.py Show resolved Hide resolved
@jcastill
Copy link
Member

A couple of very small comments from me.
The DCO is still failing, I think you are missing '-s' while running 'git commit'.
Last thing, please make sure you squash the two commits you have at the moment into one.

@jcastill
Copy link
Member

@MichaelThamm remember to squash all the commits into one and sign it

@MichaelThamm MichaelThamm changed the title Feat: Report on juju environment [Juju] Add plugin option for Juju state reporting Oct 14, 2024
@MichaelThamm MichaelThamm changed the title [Juju] Add plugin option for Juju state reporting [juju] Add plugin option for Juju state reporting Oct 14, 2024
@MichaelThamm
Copy link
Author

@arif-ali or @jcastill I imagine that I need to obfuscate some of the following information which is included in the juju controllers command output:

        "lxd": {
            "user": "admin",
            "recent-server": IP:Port,
            "uuid": "ac03821c-361e-4daf-83c9-a712cd56b8d4",
            "api-endpoints": [IP:Port],
            "ca-cert": "-----BEGIN CERTIFICATE-----
            ...
            -----END CERTIFICATE-----",
        },

Is there a need to obfuscate these things or is it just passwords, tokens, keys as mentioned in obfuscate?

@arif-ali
Copy link
Member

@MichaelThamm The IP addresses and endpoints, not so, as they would be typically handled by --clean or sos clean, if indeed these needed to be obfuscated.

In terms of the certs, you can get the example of the sunbeam.py plugin, where we just needs self.do_cmd_private_sub('juju controllers') in the postproc() function. This will automatically obfuscate any command that showed the cert.

sos/report/plugins/juju.py Outdated Show resolved Hide resolved
sos/report/plugins/juju.py Outdated Show resolved Hide resolved
sos/report/plugins/juju.py Show resolved Hide resolved
sos/report/plugins/juju.py Outdated Show resolved Hide resolved
sos/report/plugins/juju.py Outdated Show resolved Hide resolved
@MichaelThamm
Copy link
Author

@arif-ali

In terms of the certs, you can get the example of the sunbeam.py plugin, where we just needs self.do_cmd_private_sub('juju controllers') in the postproc() function. This will automatically obfuscate any command that showed the cert.

When I run: self.do_cmd_private_sub('juju controllers --format=json') I see this in the logs:

2024-10-15 10:13:54,360 DEBUG: [plugin:juju] substituting '-----SCRUBBED' for '----(?:-| )BEGIN.*?----(?:-| )END' in commands matching '*juju controllers --format=json*'

However, I do not see results in the commands dir of the sos report tar.xz file

This method does not have a filename parameter either. Not sure how to continue with this?

@arif-ali
Copy link
Member

When I run: self.do_cmd_private_sub('juju controllers --format=json') I see this in the logs:

2024-10-15 10:13:54,360 DEBUG: [plugin:juju] substituting '-----SCRUBBED' for '----(?:-| )BEGIN.*?----(?:-| )END' in commands matching '*juju controllers --format=json*'

However, I do not see results in the commands dir of the sos report tar.xz file

This method does not have a filename parameter either. Not sure how to continue with this?

You can just specify juju controllers in the function, and it will do a match. In the sunbeam.py, I did the same with doing a self.collect_cmd_output("juju controllers --format json"), and then used the juju controllers in the self.do_cmd_private_sub()

@MichaelThamm
Copy link
Author

I think the PR is almost ready for review, but I noticed we have tests for the Juju plugin. Is there any need to update this since the test for scrubbing seems to be sufficient? I also tested the scrubbing for juju controllers manually and it passes.

@MichaelThamm MichaelThamm marked this pull request as ready for review October 15, 2024 15:41
)
if controllers_json["status"] == 0:
desired_controllers = set(
self.get_option("controllers").split(" ")
Copy link
Member

Choose a reason for hiding this comment

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

We generally have plugins use : as a delimiter in plugin options that can take a list (as the use of commas gets murky with argparse and how plugin options are....parsed.

Copy link
Author

@MichaelThamm MichaelThamm Oct 16, 2024

Choose a reason for hiding this comment

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

The only problem with this is for the Juju model synatx it can be:

  • The current controller's model -> model_a
  • Or it can be a specific controller and model -> controller_x:model_a

For this reason I chose to split via empty space since models and controllers are not allowed to have spaces in their names according to Juju.

i.e. controller one -> not valid name

Would this be a reasonable exception to the Sos plugin standard?

Copy link
Member

Choose a reason for hiding this comment

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

If it's an expectation that users would pass something like -k juju.controllers="foo:bar", then yeah it's totally reasonable to use something else. We should just make note of that, ideally in both the plugin option description (for sos report -l output) and the docstring for the plugin (as the docstring gets used in sos help output, e.g. sos help report.plugins.juju - see the kernel plugin docstring for a good example).


# Specific models
if self.get_option("models"):
for model in self.get_option("models").split(" "):
Copy link
Member

Choose a reason for hiding this comment

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

Ditto, we prefer plugin options to use : as a delimiter. We may need to add this to the plugin guide, I'll check this shortly.

if self.get_option("models"):
for model in self.get_option("models").split(" "):
command = f"juju status -m {model} --format=json"
self.collect_cmd_output(command, runas=juju_user)
Copy link
Member

Choose a reason for hiding this comment

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

collect_cmd_output() is designed to return the output for further processing, if you don't need to do anything with the output, use add_cmd_output() instead.

f"juju status -m {controller}:{short_name} "
f"--format=json"
)
self.collect_cmd_output(command, runas=juju_user)
Copy link
Member

Choose a reason for hiding this comment

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

Same here, use add_cmd_output() if you don't need to do anything further with the output.

Comment on lines +99 to +104
if self.get_option("controllers") and self.get_option("models"):
self._log_warn(
"Options: controllers, models are mutually exclusive. "
"Will not collect Juju information."
)
return
Copy link
Member

Choose a reason for hiding this comment

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

I'm assuming these are mutually exclusive within the Juju stack, but would we not anticipate some (admittedly niche) use case where an sos end user isn't sure if a particular host is using one or the other, and wants to pass e.g. -k juju.controllers=foo,juju.models=bar to get either without needing to know the specific host configuration? I'm mainly thinking of some sort of automation-driven sos collection here, but I could be way off with that idea.

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.

4 participants