Skip to content

Commit

Permalink
Feat: Report on juju environment
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaelThamm committed Oct 9, 2024
1 parent 0ab183d commit 43eeb54
Showing 1 changed file with 60 additions and 2 deletions.
62 changes: 60 additions & 2 deletions sos/report/plugins/juju.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@
#
# See the LICENSE file in the source distribution for further information.

from sos.report.plugins import Plugin, UbuntuPlugin

from sos.report.plugins import Plugin, UbuntuPlugin, PluginOpt
import pwd
import json

class Juju(Plugin, UbuntuPlugin):

Expand All @@ -22,6 +23,17 @@ class Juju(Plugin, UbuntuPlugin):
# package on a juju machine.
files = ('/var/log/juju',)

option_list = [
PluginOpt('is-feature', default=False, val_type=bool,
desc='Apply PR feature functionality'),
PluginOpt('juju-user', default='ubuntu', val_type=str,
desc='Juju client user'),
PluginOpt('controllers', default='', val_type=str,
desc='collect for specified Juju controllers'),
PluginOpt('models', default='', val_type=str,
desc='collect for specified Juju models'),
]

def setup(self):
# Juju service names are not consistent through deployments,
# so we need to use a wildcard to get the correct service names.
Expand Down Expand Up @@ -53,6 +65,52 @@ def setup(self):
# logs in the directory.
self.add_copy_spec("/var/log/juju/*.log")

# Only run the feature code if this plugin option is set
if not self.get_option("is-feature"):
return

juju_user = self.get_option("juju-user")
try:
pwd.getpwnam(juju_user)
except KeyError:
# The user doesn't exist, this will skip the rest
self._log_warn(f'User "{juju_user}" does not exist, will not collect Juju information.')
return

user_context = f'sudo -u {juju_user}'

controllers_json = self.collect_cmd_output(f"{user_context} juju controllers --format=json")
if controllers_json['status'] == 0:
desired_controllers = set(self.get_option('controllers').split(' '))
# If a controller option is supplied, use it. Otherwise, get all controllers
if desired_controllers and desired_controllers != {''}:
controllers = desired_controllers
else:
controllers = set(json.loads(controllers_json["output"])["controllers"].keys())
else:
controllers = {}

if self.get_option('controllers') and self.get_option('models'):
self._log_warn('Options: controllers, models are mutually exclusive.')
return

# Specific models
if self.get_option('models'):
models = self.get_option('models').split(' ')
commands = [f"{user_context} juju status -m {model} --format=json" for model in models]
for command in commands:
self.collect_cmd_output(command)

# All controllers and all models OR specific controllers and all models for each
else:
for controller in controllers:
models_json = self.exec_cmd(f"{user_context} juju models --all -c {controller} --format=json")
if models_json['status'] == 0:
models = [model['short-name'] for model in json.loads(models_json['output'])["models"]]
commands = [f"{user_context} juju status -m {controller}:{model} --format=json" for model in models]
for command in commands:
self.collect_cmd_output(command)

def postproc(self):
agents_path = "/var/lib/juju/agents/*"
protect_keys = [
Expand Down

0 comments on commit 43eeb54

Please sign in to comment.