Skip to content

Commit

Permalink
Merge pull request #240 from opsmill/wvd-release-1.6.1
Browse files Browse the repository at this point in the history
  • Loading branch information
lykinsbd authored Jan 17, 2025
2 parents 1db17a9 + ddadf3a commit dbbe385
Show file tree
Hide file tree
Showing 22 changed files with 327 additions and 305 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,10 @@ jobs:
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: "Set environment variables"
run: |
RUNNER_NAME=$(echo "${{ runner.name }}" | grep -o 'ghrunner[0-9]\+' | sed 's/ghrunner\([0-9]\+\)/ghrunner_\1/')
echo "PYTEST_DEBUG_TEMPROOT=/var/lib/github/${RUNNER_NAME}/_temp" >> $GITHUB_ENV
- name: "Setup environment"
run: |
pipx install poetry==1.8.5
Expand Down
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,24 @@ This project uses [*towncrier*](https://towncrier.readthedocs.io/) and the chang

<!-- towncrier release notes start -->

## [1.6.1](https://github.com/opsmill/infrahub-sdk-python/tree/v1.6.1) - 2025-01-16

Fixes release of v1.6.0

## [1.6.0](https://github.com/opsmill/infrahub-sdk-python/tree/v1.6.0) - 2025-01-16

### Added

- Replace GitPython with dulwich ([#130](https://github.com/opsmill/infrahub-sdk-python/issues/130))

### Changed

- Added possibility to use filters for the SDK client's count method

### Fixed

- Fixes issue where using `parallel` query execution could lead to excessive and unneeded GraphQL queries

## [1.5.0](https://github.com/opsmill/infrahub-sdk-python/tree/v1.5.0) - 2025-01-09

### Added
Expand Down
2 changes: 1 addition & 1 deletion infrahub_sdk/analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def variables(self) -> list[GraphQLQueryVariable]:
else:
data["default_value"] = variable.default_value.value

if not data.get("default_value", None) and non_null:
if not data.get("default_value") and non_null:
data["required"] = True

response.append(GraphQLQueryVariable(**data))
Expand Down
8 changes: 4 additions & 4 deletions infrahub_sdk/checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@
from typing import TYPE_CHECKING, Any

import ujson
from git.repo import Repo
from pydantic import BaseModel, Field

from infrahub_sdk.repository import GitRepoManager

from .exceptions import UninitializedError

if TYPE_CHECKING:
Expand Down Expand Up @@ -43,7 +44,7 @@ def __init__(
params: dict | None = None,
client: InfrahubClient | None = None,
):
self.git: Repo | None = None
self.git: GitRepoManager | None = None
self.initializer = initializer or InfrahubCheckInitializer()

self.logs: list[dict[str, Any]] = []
Expand Down Expand Up @@ -137,10 +138,9 @@ def branch_name(self) -> str:
return self.branch

if not self.git:
self.git = Repo(self.root_directory)
self.git = GitRepoManager(self.root_directory)

self.branch = str(self.git.active_branch)

return self.branch

@abstractmethod
Expand Down
42 changes: 26 additions & 16 deletions infrahub_sdk/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -547,16 +547,21 @@ async def count(
at: Timestamp | None = None,
branch: str | None = None,
timeout: int | None = None,
**kwargs: Any,
) -> int:
"""Return the number of nodes of a given kind."""
filters = kwargs
schema = await self.schema.get(kind=kind, branch=branch)

branch = branch or self.default_branch
if at:
at = Timestamp(at)

response = await self.execute_graphql(
query=Query(query={schema.kind: {"count": None}}).render(), branch_name=branch, at=at, timeout=timeout
query=Query(query={schema.kind: {"count": None, "@filters": filters}}).render(),
branch_name=branch,
at=at,
timeout=timeout,
)
return int(response.get(schema.kind, {}).get("count", 0))

Expand Down Expand Up @@ -781,7 +786,7 @@ async def process_batch() -> tuple[list[InfrahubNode], list[InfrahubNode]]:
nodes = []
related_nodes = []
batch_process = await self.create_batch()
count = await self.count(kind=schema.kind)
count = await self.count(kind=schema.kind, **filters)
total_pages = (count + pagination_size - 1) // pagination_size

for page_number in range(1, total_pages + 1):
Expand Down Expand Up @@ -1181,7 +1186,7 @@ async def allocate_next_ip_address(
async def allocate_next_ip_address(
self,
resource_pool: CoreNode,
kind: Literal[None] = ...,
kind: None = ...,
identifier: str | None = ...,
prefix_length: int | None = ...,
address_type: str | None = ...,
Expand All @@ -1196,7 +1201,7 @@ async def allocate_next_ip_address(
async def allocate_next_ip_address(
self,
resource_pool: CoreNode,
kind: Literal[None] = ...,
kind: None = ...,
identifier: str | None = ...,
prefix_length: int | None = ...,
address_type: str | None = ...,
Expand All @@ -1211,7 +1216,7 @@ async def allocate_next_ip_address(
async def allocate_next_ip_address(
self,
resource_pool: CoreNode,
kind: Literal[None] = ...,
kind: None = ...,
identifier: str | None = ...,
prefix_length: int | None = ...,
address_type: str | None = ...,
Expand Down Expand Up @@ -1328,7 +1333,7 @@ async def allocate_next_ip_prefix(
async def allocate_next_ip_prefix(
self,
resource_pool: CoreNode,
kind: Literal[None] = ...,
kind: None = ...,
identifier: str | None = ...,
prefix_length: int | None = ...,
member_type: str | None = ...,
Expand All @@ -1344,7 +1349,7 @@ async def allocate_next_ip_prefix(
async def allocate_next_ip_prefix(
self,
resource_pool: CoreNode,
kind: Literal[None] = ...,
kind: None = ...,
identifier: str | None = ...,
prefix_length: int | None = ...,
member_type: str | None = ...,
Expand All @@ -1360,7 +1365,7 @@ async def allocate_next_ip_prefix(
async def allocate_next_ip_prefix(
self,
resource_pool: CoreNode,
kind: Literal[None] = ...,
kind: None = ...,
identifier: str | None = ...,
prefix_length: int | None = ...,
member_type: str | None = ...,
Expand Down Expand Up @@ -1651,16 +1656,21 @@ def count(
at: Timestamp | None = None,
branch: str | None = None,
timeout: int | None = None,
**kwargs: Any,
) -> int:
"""Return the number of nodes of a given kind."""
filters = kwargs
schema = self.schema.get(kind=kind, branch=branch)

branch = branch or self.default_branch
if at:
at = Timestamp(at)

response = self.execute_graphql(
query=Query(query={schema.kind: {"count": None}}).render(), branch_name=branch, at=at, timeout=timeout
query=Query(query={schema.kind: {"count": None, "@filters": filters}}).render(),
branch_name=branch,
at=at,
timeout=timeout,
)
return int(response.get(schema.kind, {}).get("count", 0))

Expand Down Expand Up @@ -1920,7 +1930,7 @@ def process_batch() -> tuple[list[InfrahubNodeSync], list[InfrahubNodeSync]]:
related_nodes = []
batch_process = self.create_batch()

count = self.count(kind=schema.kind)
count = self.count(kind=schema.kind, **filters)
total_pages = (count + pagination_size - 1) // pagination_size

for page_number in range(1, total_pages + 1):
Expand Down Expand Up @@ -2296,7 +2306,7 @@ def allocate_next_ip_address(
def allocate_next_ip_address(
self,
resource_pool: CoreNodeSync,
kind: Literal[None] = ...,
kind: None = ...,
identifier: str | None = ...,
prefix_length: int | None = ...,
address_type: str | None = ...,
Expand All @@ -2311,7 +2321,7 @@ def allocate_next_ip_address(
def allocate_next_ip_address(
self,
resource_pool: CoreNodeSync,
kind: Literal[None] = ...,
kind: None = ...,
identifier: str | None = ...,
prefix_length: int | None = ...,
address_type: str | None = ...,
Expand All @@ -2326,7 +2336,7 @@ def allocate_next_ip_address(
def allocate_next_ip_address(
self,
resource_pool: CoreNodeSync,
kind: Literal[None] = ...,
kind: None = ...,
identifier: str | None = ...,
prefix_length: int | None = ...,
address_type: str | None = ...,
Expand Down Expand Up @@ -2439,7 +2449,7 @@ def allocate_next_ip_prefix(
def allocate_next_ip_prefix(
self,
resource_pool: CoreNodeSync,
kind: Literal[None] = ...,
kind: None = ...,
identifier: str | None = ...,
prefix_length: int | None = ...,
member_type: str | None = ...,
Expand All @@ -2455,7 +2465,7 @@ def allocate_next_ip_prefix(
def allocate_next_ip_prefix(
self,
resource_pool: CoreNodeSync,
kind: Literal[None] = ...,
kind: None = ...,
identifier: str | None = ...,
prefix_length: int | None = ...,
member_type: str | None = ...,
Expand All @@ -2471,7 +2481,7 @@ def allocate_next_ip_prefix(
def allocate_next_ip_prefix(
self,
resource_pool: CoreNodeSync,
kind: Literal[None] = ...,
kind: None = ...,
identifier: str | None = ...,
prefix_length: int | None = ...,
member_type: str | None = ...,
Expand Down
6 changes: 3 additions & 3 deletions infrahub_sdk/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from abc import abstractmethod
from typing import TYPE_CHECKING

from git.repo import Repo
from infrahub_sdk.repository import GitRepoManager

from .exceptions import UninitializedError

Expand All @@ -30,7 +30,7 @@ def __init__(
) -> None:
self.query = query
self.branch = branch
self.git: Repo | None = None
self.git: GitRepoManager | None = None
self.params = params or {}
self.root_directory = root_directory or os.getcwd()
self.generator_instance = generator_instance
Expand Down Expand Up @@ -81,7 +81,7 @@ def branch_name(self) -> str:
return self.branch

if not self.git:
self.git = Repo(self.root_directory)
self.git = GitRepoManager(self.root_directory)

self.branch = str(self.git.active_branch)

Expand Down
4 changes: 2 additions & 2 deletions infrahub_sdk/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -1074,7 +1074,7 @@ async def from_graphql(
timeout: int | None = None,
) -> Self:
if not schema:
node_kind = data.get("__typename", None) or data.get("node", {}).get("__typename", None)
node_kind = data.get("__typename") or data.get("node", {}).get("__typename", None)
if not node_kind:
raise ValueError("Unable to determine the type of the node, __typename not present in data")
schema = await client.schema.get(kind=node_kind, branch=branch, timeout=timeout)
Expand Down Expand Up @@ -1594,7 +1594,7 @@ def from_graphql(
timeout: int | None = None,
) -> Self:
if not schema:
node_kind = data.get("__typename", None) or data.get("node", {}).get("__typename", None)
node_kind = data.get("__typename") or data.get("node", {}).get("__typename", None)
if not node_kind:
raise ValueError("Unable to determine the type of the node, __typename not present in data")
schema = client.schema.get(kind=node_kind, branch=branch, timeout=timeout)
Expand Down
5 changes: 0 additions & 5 deletions infrahub_sdk/pytest_plugin/items/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

import pytest
import ujson
from git.exc import InvalidGitRepositoryError

from ..exceptions import InvalidResourceConfigError
from ..models import InfrahubInputOutputTest
Expand All @@ -28,7 +27,6 @@ def __init__(
**kwargs: dict[str, Any],
):
super().__init__(*args, **kwargs) # type: ignore[arg-type]

self.resource_name: str = resource_name
self.resource_config: InfrahubRepositoryConfigElement = resource_config
self.test: InfrahubTest = test
Expand Down Expand Up @@ -68,9 +66,6 @@ def runtest(self) -> None:
"""Run the test logic."""

def repr_failure(self, excinfo: pytest.ExceptionInfo, style: str | None = None) -> str: # noqa: ARG002
if isinstance(excinfo.value, InvalidGitRepositoryError):
return f"Invalid Git repository at {excinfo.value}"

return str(excinfo.value)

def reportinfo(self) -> tuple[Path | str, int | None, str]:
Expand Down
33 changes: 33 additions & 0 deletions infrahub_sdk/repository.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from __future__ import annotations

from pathlib import Path

from dulwich import porcelain
from dulwich.repo import Repo


class GitRepoManager:
def __init__(self, root_directory: str, branch: str = "main"):
self.root_directory = root_directory
self.branch = branch
self.git: Repo = self.initialize_repo()

def initialize_repo(self) -> Repo:
# Check if the directory already has a repository

root_path = Path(self.root_directory)

if root_path.exists() and (root_path / ".git").is_dir():
repo = Repo(self.root_directory) # Open existing repo
else:
repo = Repo.init(self.root_directory, default_branch=self.branch.encode("utf-8"))

if not repo:
raise ValueError("Failed to initialize or open a repository.")

return repo

@property
def active_branch(self) -> str | None:
active_branch = porcelain.active_branch(self.root_directory).decode("utf-8")
return active_branch
Loading

0 comments on commit dbbe385

Please sign in to comment.