Skip to content

Commit

Permalink
Merge pull request #349 from rackerlabs/pre-commit
Browse files Browse the repository at this point in the history
  • Loading branch information
cardoe authored Sep 25, 2024
2 parents 6a1b70b + f760723 commit 057fa03
Show file tree
Hide file tree
Showing 25 changed files with 482 additions and 254 deletions.
27 changes: 27 additions & 0 deletions .github/workflows/pre-commit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
name: pre-commit

on: # yamllint disable-line rule:truthy
pull_request:
push:
branches:
- main

jobs:
pre-commit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
id: setup-python
with:
python-version: '3.11'
cache: 'pip'
- uses: actions/cache@v4
with:
path: ~/.cache/pre-commit
key: pre-commit-${{ hashFiles('.pre-commit-config.yaml') }}
- run: pip install pre-commit
- name: "run pre-commit"
run: |
pre-commit run --all-files --show-diff-on-failure
20 changes: 2 additions & 18 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ repos:
rev: v4.5.0
hooks:
- id: trailing-whitespace
exclude: '\.patch'
- id: end-of-file-fixer
exclude: '^docs/overrides'
- id: fix-byte-order-marker
- id: mixed-line-ending
- id: check-yaml
Expand All @@ -16,22 +18,6 @@ repos:
hooks:
- id: yamllint
args: [-c, .yamllint.yaml]
- repo: https://github.com/PyCQA/flake8
rev: 7.0.0
hooks:
- id: flake8
exclude: '^python/'
args:
- --max-line-length=120
- repo: https://github.com/psf/black
rev: 24.4.2
hooks:
- id: black
exclude: '^python/'
args:
- --line-length=120
- --check
- --diff
- repo: https://github.com/python-jsonschema/check-jsonschema
rev: 0.28.4
hooks:
Expand All @@ -54,10 +40,8 @@ repos:
rev: v0.5.4
hooks:
- id: ruff
files: '^python/'
args: [--fix]
- id: ruff-format
files: '^python/'
- repo: https://github.com/python-poetry/poetry
rev: '1.7.1'
hooks:
Expand Down
4 changes: 1 addition & 3 deletions components/nautobot/dexauth.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ def _env_list(field: str, default: str) -> list[str]:
STAFF_GROUPS = _env_list("DEX_STAFF_GROUPS", "ucadmin")


def group_sync(
uid, user=None, response=None, *args, **kwargs
): # pylint: disable=keyword-arg-before-vararg, unused-argument
def group_sync(uid, user=None, response=None, *args, **kwargs): # pylint: disable=keyword-arg-before-vararg, unused-argument
"""Sync the users groups from the response and set staff/superuser as
appropriate"""
if user and response and response.get(GROUPS_ATTR_NAME, False):
Expand Down
8 changes: 6 additions & 2 deletions components/nautobot/nautobot_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,9 @@

# Send anonymized installation metrics when `nautobot-server post_upgrade` command is run.
#
INSTALLATION_METRICS_ENABLED = is_truthy(os.getenv("NAUTOBOT_INSTALLATION_METRICS_ENABLED", "True"))
INSTALLATION_METRICS_ENABLED = is_truthy(
os.getenv("NAUTOBOT_INSTALLATION_METRICS_ENABLED", "True")
)

# Storage backend to use for Job input files and Job output files.
#
Expand Down Expand Up @@ -467,7 +469,9 @@ def _read_cred(filename):


# configure our SSO login from our secret
SOCIAL_AUTH_OIDC_OIDC_ENDPOINT = _read_cred("/opt/nautobot/sso/issuer") or os.getenv("SOCIAL_AUTH_OIDC_OIDC_ENDPOINT")
SOCIAL_AUTH_OIDC_OIDC_ENDPOINT = _read_cred("/opt/nautobot/sso/issuer") or os.getenv(
"SOCIAL_AUTH_OIDC_OIDC_ENDPOINT"
)
SOCIAL_AUTH_OIDC_KEY = _read_cred("/opt/nautobot/sso/client-id") or "nautobot"
SOCIAL_AUTH_OIDC_SECRET = _read_cred("/opt/nautobot/sso/client-secret")
# The “openid”, “profile” and “email” are requested by default,
Expand Down
9 changes: 8 additions & 1 deletion containers/argo_utils/code/argo_python/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,14 @@


class ArgoWorkflow:
def __init__(self, namespace: str, name: str, uid: str, api_version="argoproj.io/v1alpha1", config_file=None):
def __init__(
self,
namespace: str,
name: str,
uid: str,
api_version="argoproj.io/v1alpha1",
config_file=None,
):
if config_file:
config.load_kube_config(config_file)
else:
Expand Down
19 changes: 15 additions & 4 deletions containers/bmc-utils/code/bmc_firmware_update.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@


if __name__ == "__main__":
parser = argparse.ArgumentParser(prog=os.path.basename(__file__), description="Update BMC firmware")
parser.add_argument("--host", required=True, help="The address of the BMC interface")
parser = argparse.ArgumentParser(
prog=os.path.basename(__file__), description="Update BMC firmware"
)
parser.add_argument(
"--host", required=True, help="The address of the BMC interface"
)
parser.add_argument("--firmware-url", required=True, help="URL of firmware")

args = parser.parse_args()
Expand All @@ -41,7 +45,12 @@
"Content-Type": "multipart/form-data",
}

update_data = {"UpdateRepository": True, "UpdateTarget": True, "ETag": "atag", "Section": 0}
update_data = {
"UpdateRepository": True,
"UpdateTarget": True,
"ETag": "atag",
"Section": 0,
}

upd_url = urlparse.urljoin(c._conn._url, updsvc.http_push_uri)

Expand All @@ -57,7 +66,9 @@
("parameters", json.dumps(update_data)),
("file", (filename, r.raw, "application/octet-stream")),
]
rsp = c._conn._session.post(upd_url, files=multipart, verify=False, headers=headers)
rsp = c._conn._session.post(
upd_url, files=multipart, verify=False, headers=headers
)
logger.info(rsp.json())
except Exception as e:
logger.error(e)
Expand Down
41 changes: 33 additions & 8 deletions containers/bmc-utils/code/bmc_sync_creds.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,21 @@


def redfish_request(
host: str, uri: str, username: str, password: str, method: str = "GET", payload: Dict | None = None
host: str,
uri: str,
username: str,
password: str,
method: str = "GET",
payload: Dict | None = None,
) -> dict:
try:
r = requests.request(
method, f"https://{host}{uri}", verify=False, auth=(username, password), timeout=15, json=payload
method,
f"https://{host}{uri}",
verify=False,
auth=(username, password),
timeout=15,
json=payload,
)
r.raise_for_status()
return r.json()
Expand Down Expand Up @@ -67,7 +77,13 @@ def get_bmc_accounts(host: str, username: str, password: str) -> List[Dict]:
raise


def set_bmc_creds(host: str, username: str, password: str, expected_username: str, expected_password: str) -> bool:
def set_bmc_creds(
host: str,
username: str,
password: str,
expected_username: str,
expected_password: str,
) -> bool:
"""Find the account associated with the username in question"""
try:
accounts = get_bmc_accounts(host, username, password)
Expand Down Expand Up @@ -97,9 +113,12 @@ def set_bmc_creds(host: str, username: str, password: str, expected_username: st

if __name__ == "__main__":
parser = argparse.ArgumentParser(
prog=os.path.basename(__file__), description="Attempts to find the correct BMC credentials for a device"
prog=os.path.basename(__file__),
description="Attempts to find the correct BMC credentials for a device",
)
parser.add_argument(
"--host", required=True, help="the address of the bmc interface for the device"
)
parser.add_argument("--host", required=True, help="the address of the bmc interface for the device")

args = parser.parse_args()
host = args.host
Expand All @@ -117,17 +136,23 @@ def set_bmc_creds(host: str, username: str, password: str, expected_username: st
logger.info("BMC credentials are in sync.")
sys.exit(0)
else:
logger.info("BMC credentials are NOT in sync. Trying known legacy/vendor credentials ...")
logger.info(
"BMC credentials are NOT in sync. Trying known legacy/vendor credentials ..."
)

# iDRAC defaults to blocking an IP address after 3 bad login attempts within 60 second. Since we have the
# initial attempt above, we will sleep 35 seconds between any additional attempts.
delay = 60
username = os.getenv("BMC_LEGACY_USER", "root")
for password in legacy_passwords:
logger.info(f"Delaying for {delay} seconds to prevent failed auth lockouts ...")
logger.info(
f"Delaying for {delay} seconds to prevent failed auth lockouts ..."
)
time.sleep(delay)
if verify_auth(host, username, password):
if set_bmc_creds(host, username, password, expected_username, expected_password):
if set_bmc_creds(
host, username, password, expected_username, expected_password
):
logger.info("BMC password has been synced.")
sys.exit(0)

Expand Down
1 change: 1 addition & 0 deletions python/ironic-understack/ironic_understack/conf.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from oslo_config import cfg

CONF = cfg.CONF


Expand Down
7 changes: 3 additions & 4 deletions python/ironic-understack/ironic_understack/flavor_spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,11 @@ def score_machine(self, machine: Machine):
# but more memory space it is less desirable than the machine that
# matches exactly on both disk and memory.


# Rule 1: 100% match gets the highest priority
if (
machine.memory_gb == self.memory_gb and
machine.disk_gb in self.drives and
machine.cpu in self.cpu_models
machine.memory_gb == self.memory_gb
and machine.disk_gb in self.drives
and machine.cpu in self.cpu_models
):
return 100

Expand Down
1 change: 0 additions & 1 deletion python/ironic-understack/ironic_understack/machine.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,3 @@ class Machine:
@property
def memory_gb(self) -> int:
return self.memory_mb // 1024

Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def inspect_hardware(self, task):
:returns: The resulting state of inspection.
"""
upstream_state = super().inspect_hardware(task) # pyright: ignore reportAttributeAccessIssue
upstream_state = super().inspect_hardware(task) # pyright: ignore reportAttributeAccessIssue

inspection_data = get_inspection_data(task.node, task.context)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,12 @@ def test_empty_directory(tmp_path):
specs = FlavorSpec.from_directory(str(tmp_path))
assert len(specs) == 0


@pytest.fixture
def machines():
return [
# 1024 GB, exact CPU, medium
Machine(
memory_mb=102400, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=1000
),
Machine(memory_mb=102400, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=1000),
# 800 GB, non-matching CPU
Machine(memory_mb=800000, cpu="Intel Xeon E5-2676 v3", disk_gb=500),
# 200 GB, exact CPU, medium
Expand Down Expand Up @@ -140,19 +139,26 @@ def flavors():
),
]


def test_exact_match(flavors):
machine = Machine(memory_mb=102400, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=500)
machine = Machine(
memory_mb=102400, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=500
)
assert flavors[0].score_machine(machine) == 100
assert flavors[1].score_machine(machine) == 0


def test_memory_too_small(flavors):
machine = Machine(memory_mb=51200, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=500)
machine = Machine(
memory_mb=51200, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=500
)
assert all(flavor.score_machine(machine) for flavor in flavors) == 0


def test_disk_too_small(flavors):
machine = Machine(memory_mb=204800, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=100)
machine = Machine(
memory_mb=204800, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=100
)
assert all(flavor.score_machine(machine) for flavor in flavors) == 0


Expand All @@ -162,51 +168,66 @@ def test_cpu_model_not_matching(flavors):


def test_memory_match_but_more_disk(flavors):
machine = Machine(memory_mb=102400, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=1000)
machine = Machine(
memory_mb=102400, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=1000
)
assert flavors[0].score_machine(machine) > 0


def test_disk_match_but_more_memory(flavors):
machine = Machine(memory_mb=204800, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=500)
machine = Machine(
memory_mb=204800, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=500
)

assert flavors[0].score_machine(machine) > 0
assert flavors[1].score_machine(machine) == 0
assert flavors[2].score_machine(machine) == 0


# Edge cases
def test_memory_slightly_less(flavors):
# Machine with slightly less memory than required by the smallest flavor
machine = Machine(memory_mb=102300, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=500)
machine = Machine(
memory_mb=102300, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=500
)
# Should not match because memory is slightly less
assert all(flavor.score_machine(machine) for flavor in flavors) == 0


def test_disk_slightly_less(flavors):
# Machine with slightly less disk space than required by the smallest flavor
machine = Machine(memory_mb=102400, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=499)
machine = Machine(
memory_mb=102400, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=499
)
# Should not match because disk space is slightly less
assert all(flavor.score_machine(machine) for flavor in flavors) == 0


def test_memory_exact_disk_slightly_more(flavors):
# Machine with exact memory but slightly more disk space than required
machine = Machine(memory_mb=102400, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=501)
machine = Machine(
memory_mb=102400, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=501
)
assert flavors[0].score_machine(machine) > 0
assert flavors[1].score_machine(machine) == 0
assert flavors[2].score_machine(machine) == 0


def test_disk_exact_memory_slightly_more(flavors):
# Machine with exact disk space but slightly more memory than required
machine = Machine(memory_mb=102500, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=500)
machine = Machine(
memory_mb=102500, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=500
)
assert flavors[0].score_machine(machine) > 0
assert flavors[1].score_machine(machine) == 0
assert flavors[2].score_machine(machine) == 0


def test_cpu_model_not_exact_but_memory_and_disk_match(flavors):
# Machine with exact memory and disk space but CPU model is close but not exact
machine = Machine(memory_mb=102400, cpu="AMD EPYC 9254 245-Core Processor v2", disk_gb=500)
machine = Machine(
memory_mb=102400, cpu="AMD EPYC 9254 245-Core Processor v2", disk_gb=500
)
# Should not match because CPU model is not exactly listed
assert all(flavor.score_machine(machine) for flavor in flavors) == 0

Expand Down
Loading

0 comments on commit 057fa03

Please sign in to comment.