Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 12 additions & 13 deletions .github/workflows/test-xjs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,18 @@ jobs:
python -m pip install --upgrade pip
pip install flake8 pycodestyle
pip install -r requirements.txt
pycodestyle xjs
flake8 xjs
pycodestyle xjs/
flake8 xjs/

- name: Run xjs tests
run: |
python3 xjs examples/example.json
python3 xjs examples/example.json
python3 xjs examples/example.yaml
python3 xjs examples/example2.yaml
python3 xjs examples/example.json examples/example2.json
python3 xjs --application glance examples/example.json
python3 xjs --application rabbitmq-server examples/example.json
python3 xjs --model k8s examples/example2.json
python3 xjs --controller controller examples/example.json examples/example2.json
python3 xjs --unit k8s/0 examples/example2.json
python3 xjs --subordinate ovn-chassis/0 examples/example.json
python3 -m xjs examples/example.json
python3 -m xjs examples/example.yaml
python3 -m xjs examples/example2.yaml
python3 -m xjs examples/example.json examples/example2.json
python3 -m xjs --application glance examples/example.json
python3 -m xjs --application rabbitmq-server examples/example.json
python3 -m xjs --model k8s examples/example2.json
python3 -m xjs --controller controller examples/example.json examples/example2.json
python3 -m xjs --unit k8s/0 examples/example2.json
python3 -m xjs --subordinate ovn-chassis/0 examples/example.json
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
__pycache__
venv
*.snap
14 changes: 14 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
xjs - offline juju status viewer
Copyright 2019 Canonical Ltd.

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License version 3 as
published by the Free Software Foundation.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,11 @@ Options:
-d, --show-model Show model information
-n, --show-net Show network interface information
-u, --show-units Show unit information
-r, --show-relations Show relation information
--subordinate <subordinate name>
Show only the subordinate unit with the
specified name
--unit <unit name> Show only the unit with the specified name
--version Show the version and exit.
--help Show this message and exit.
```
15 changes: 15 additions & 0 deletions my.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# XJS Codebase Analysis

## 🐛 Bugs & Defects

## 🧹 Code Quality & Maintainability

## 🏗 Architecture & Design

## ⚡ Performance

## ✨ Missing Features

## 🔧 CI/CD & Tooling

## 📝 Minor / Cosmetic
27 changes: 27 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
[build-system]
requires = ["setuptools>=64"]
build-backend = "setuptools.build_meta"

[project]
name = "xjs"
version = "0.1"
description = "A tool to parse and display offline juju status files"
license = "GPL-3.0-only"
requires-python = ">=3.12"
dependencies = [
"PyYAML >= 6.0.3",
"prettytable >= 3.17.0",
"click >= 8.3.1",
"packaging >= 26.0",
"pendulum >= 3.2.0",
]

[project.urls]
Source = "https://github.com/WizardBit/xjs/"

[tool.setuptools.packages.find]
include = ["xjs*"]
exclude = ["snap*"]

[project.scripts]
xjs = "xjs.cli:main"
1 change: 0 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,4 @@ PyYAML >= 6.0.3
prettytable >= 3.17.0
click >= 8.3.1
packaging >= 26.0
requests >= 2.32.5
pendulum >= 3.2.0
46 changes: 0 additions & 46 deletions setup.py

This file was deleted.

6 changes: 3 additions & 3 deletions snapit
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ snapcraft --debug
snapcraft clean

# Install with:
# sudo snap install supctl_0.1_amd64.snap --devmode --dangerous
# sudo snap install xjs_0.1_amd64.snap --devmode --dangerous

# OLD CMDS
# source testit
# snapcraft push --release=beta ./supctl_beta2_amd64.snap
# ln supctl_beta2_amd64.snap ~/sp.snap
# snapcraft push --release=beta ./xjs_beta2_amd64.snap
# ln xjs_beta2_amd64.snap ~/sp.snap
2 changes: 2 additions & 0 deletions xjs/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# xjs - offline juju status viewer
__version__ = "0.1"
2 changes: 2 additions & 0 deletions xjs/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from .cli import main
main()
39 changes: 14 additions & 25 deletions application.py → xjs/application.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,10 @@
#!/usr/bin/env python3
# This file is part of xjs a tool used to disply offline juju status
# Copyright 2019 Canonical Ltd.
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License version 3, as published by the
# Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
# SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.
# SPDX-License-Identifier: GPL-3.0-only

import re
from colors import Color
from .colors import Color
import pendulum
from unit import Unit
from .unit import Unit


class Application:
Expand All @@ -41,7 +28,7 @@ def __init__(self, appname, appinfo=None, model=""):
object from a juju status output
"""
appinfo = appinfo if isinstance(appinfo, dict) else {}

# Default Values
self.notes = []
self.units = {}
Expand All @@ -60,11 +47,10 @@ def __init__(self, appname, appinfo=None, model=""):

base = appinfo.get("base")
if isinstance(base, dict):
self.base = f"{base.get('name','')}@{base.get('channel','')}"
self.base = f"{base.get('name', '')}@{base.get('channel', '')}"
else:
self.base = base or "NA"


if "os" in appinfo:
self.os = appinfo["os"]
else:
Expand Down Expand Up @@ -104,7 +90,9 @@ def __init__(self, appname, appinfo=None, model=""):

if statuskey in appinfo and "since" in appinfo[statuskey]:
if re.match(r".*Z$", appinfo[statuskey]["since"]):
appinfo[statuskey]["since"] = re.sub(r"Z$", "", appinfo[statuskey]["since"])
appinfo[statuskey]["since"] = re.sub(
r"Z$", "", appinfo[statuskey]["since"]
)
self.since = pendulum.from_format(
appinfo[statuskey]["since"],
"DD MMM YYYY HH:mm:ss",
Expand Down Expand Up @@ -154,7 +142,7 @@ def __init__(self, appname, appinfo=None, model=""):
unit = Unit(unitname, unitinfo, self)
self.units[unitname] = unit

def __dict__(self):
def to_dict(self):
return {self.name: self}

def add_subordinate(self, subunit):
Expand Down Expand Up @@ -208,7 +196,7 @@ def get_charmorigin_color(self):
"""
Return a charm origin string with correct colors based on the origin
"""
if self.charmorigin != "jujucharms":
if self.charmorigin != "charmhub":
return Color.Fg.Yellow + self.charmorigin + Color.Reset
else:
return self.charmorigin
Expand Down Expand Up @@ -257,11 +245,12 @@ def get_column_names(
self, include_controller_name=False, include_model_name=False
):
"""Append the controller name and/or model name as necessary"""
fields = list(self.column_names)
if include_model_name:
self.column_names.insert(0, "Model")
fields.insert(0, "Model")
if include_controller_name:
self.column_names.insert(0, "Controller")
return self.column_names
fields.insert(0, "Controller")
return fields

def filter_dictionary(self, dictionary, key_filter):
return {
Expand Down
42 changes: 17 additions & 25 deletions basicmachine.py → xjs/basicmachine.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,9 @@
#!/usr/bin/env python3
# This file is part of xjs a tool used to disply offline juju status
# Copyright 2019 Canonical Ltd.
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License version 3, as published by the
# Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
# SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.
# SPDX-License-Identifier: GPL-3.0-only

import re
from colors import Color
from networkinterface import NetworkInterface
from .colors import Color
from .networkinterface import NetworkInterface
import pendulum


Expand Down Expand Up @@ -65,7 +52,7 @@ def __init__(self, name, info, model):
self.dnsname = info["dns-name"]
else:
self.dnsname = "PENDING"
if "ipaddresses" in info:
if "ip-addresses" in info:
self.ipaddresses = info["ip-addresses"]
else:
self.ipaddresses = "NA"
Expand All @@ -79,18 +66,20 @@ def __init__(self, name, info, model):
else:
self.machinestatus = "NA"
self.machinemessage = ""

base = info.get("base")
if isinstance(base, dict):
self.base = f"{base.get('name','')}@{base.get('channel','')}"
self.base = f"{base.get('name', '')}@{base.get('channel', '')}"
else:
self.base = base if base else "NA"
self.model = model

# Required Dates
if "juju-status" in info:
if re.match(r".*Z$", info["juju-status"]["since"]):
info["juju-status"]["since"] = re.sub(r"Z$", "", info["juju-status"]["since"])
info["juju-status"]["since"] = re.sub(
r"Z$", "", info["juju-status"]["since"]
)
self.jujusince = pendulum.from_format(
info["juju-status"]["since"],
"DD MMM YYYY HH:mm:ss",
Expand All @@ -103,7 +92,9 @@ def __init__(self, name, info, model):
model.controller.update_timestamp(self.jujusince)
if "machine-status" in info:
if re.match(r".*Z$", info["machine-status"]["since"]):
info["machine-status"]["since"] = re.sub(r"Z$", "", info["machine-status"]["since"])
info["machine-status"]["since"] = re.sub(
r"Z$", "", info["machine-status"]["since"]
)
self.machinesince = pendulum.from_format(
info["machine-status"]["since"],
"DD MMM YYYY HH:mm:ss",
Expand All @@ -124,7 +115,7 @@ def __init__(self, name, info, model):
interfacename, interfaceinfo, self, model
)

def __dict__(self):
def to_dict(self):
return {self.name: self}

def get_jujustatus_color(self):
Expand Down Expand Up @@ -155,8 +146,9 @@ def get_column_names(
self, include_controller_name=False, include_model_name=False
):
"""Append the controller name and/or model name as necessary"""
fields = list(self.column_names)
if include_model_name:
self.column_names.insert(0, "Model")
fields.insert(0, "Model")
if include_controller_name:
self.column_names.insert(0, "Controller")
return self.column_names
fields.insert(0, "Controller")
return fields
Loading