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
49 changes: 43 additions & 6 deletions class_generator/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,18 +155,55 @@ class-generator --kind Pod --add-tests

## Update schema files

- Dependencies
- Kubernetes/Openshift cluster
- [oc](https://mirror.openshift.com/pub/openshift-v4/x86_64/clients/ocp/stable/) or [kubectl](https://kubernetes.io/docs/tasks/tools/) (latest version)
- [uv](https://github.com/astral-sh/uv)
Schema files contain resource definitions used by the class generator. You can update these from a connected Kubernetes/OpenShift cluster.

- Clone this repository
### Dependencies

- Kubernetes/OpenShift cluster
- [oc](https://mirror.openshift.com/pub/openshift-v4/x86_64/clients/ocp/stable/) or [kubectl](https://kubernetes.io/docs/tasks/tools/) (latest version)
- [uv](https://github.com/astral-sh/uv)

### Setup

Clone this repository:

```bash
git clone https://github.com/RedHatQE/openshift-python-wrapper.git
cd openshift-python-wrapper
```

- Login to the cluster use admin user and password.
Login to the cluster using admin user and password.

### Full schema update

Update the entire schema from the connected cluster:

```bash
class-generator --update-schema
```

This fetches all resource schemas from the cluster and updates the local cache.

**Note:** If connected to an older cluster, existing schemas are preserved and only missing resources are added.

### Single resource schema update

Update the schema for a single resource without affecting others:

```bash
class-generator --update-schema-for LlamaStackDistribution
```

This is useful when:

- Connected to an older cluster but need to update a specific CRD
- A new operator was installed and you need its resource schema
- You want to refresh just one resource without a full update

After updating the schema, regenerate the class:

```bash
class-generator --kind LlamaStackDistribution --overwrite
```

**Note:** `--update-schema` and `--update-schema-for` are mutually exclusive. Use one or the other, not both.
82 changes: 77 additions & 5 deletions class_generator/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,19 @@
from typing import Any

import cloup
from cloup.constraints import If, IsSet, accept_none, require_one
from cloup.constraints import If, IsSet, accept_none, mutually_exclusive, require_one
from simple_logger.logger import get_logger

from class_generator.constants import TESTS_MANIFESTS_DIR
from class_generator.core.coverage import analyze_coverage, generate_report
from class_generator.core.discovery import discover_generated_resources
from class_generator.core.generator import class_generator
from class_generator.core.schema import ClusterVersionError, update_kind_schema
from class_generator.core.schema import (
ClusterVersionError,
update_kind_schema,
update_single_resource_schema,
)
from class_generator.exceptions import ResourceNotFoundError
from class_generator.tests.test_generation import generate_class_generator_tests
from class_generator.utils import execute_parallel_tasks
from ocp_resources.utils.utils import convert_camel_case_to_snake_case
Expand All @@ -28,16 +33,25 @@
def validate_actions(
kind: str | None,
update_schema: bool,
update_schema_for: str | None,
discover_missing: bool,
coverage_report: bool,
generate_missing: bool,
regenerate_all: bool,
) -> None:
"""Validate that at least one action is specified."""
actions = [kind, update_schema, discover_missing, coverage_report, generate_missing, regenerate_all]
actions = [
kind,
update_schema,
update_schema_for,
discover_missing,
coverage_report,
generate_missing,
regenerate_all,
]
if not any(actions):
LOGGER.error(
"At least one action must be specified (--kind, --update-schema, --discover-missing, --coverage-report, --generate-missing, or --regenerate-all)"
"At least one action must be specified (--kind, --update-schema, --update-schema-for, --discover-missing, --coverage-report, --generate-missing, or --regenerate-all)"
)
sys.exit(1)

Expand Down Expand Up @@ -70,6 +84,33 @@ def handle_schema_update(update_schema: bool, generate_missing: bool) -> bool:
return True


def handle_single_schema_update(update_schema_for: str | None) -> bool:
"""
Handle single resource schema update operations.

Args:
update_schema_for: The kind name to update schema for, or None

Returns:
True if processing should continue, False if it should exit
"""
if update_schema_for:
LOGGER.info(f"Updating schema for single resource: {update_schema_for}")
try:
update_single_resource_schema(kind=update_schema_for)
except ResourceNotFoundError as e:
LOGGER.error(f"Resource not found: {e}")
sys.exit(1)
except (OSError, RuntimeError) as e:
LOGGER.exception(f"Failed to update schema for {update_schema_for}: {e}")
sys.exit(1)

LOGGER.info(f"Schema updated for {update_schema_for}.")
return False

return True


def handle_coverage_analysis_and_reporting(
coverage_report: bool,
discover_missing: bool,
Expand Down Expand Up @@ -491,6 +532,17 @@ def handle_test_generation(add_tests: bool) -> None:
is_flag=True,
show_default=True,
)
@cloup.option(
"--update-schema-for",
type=cloup.STRING,
help="""
\b
Update schema for a single resource kind only, without affecting other resources.
Useful when connected to an older cluster but needing to update a specific CRD.
Example: --update-schema-for LlamaStackDistribution
Cannot be used together with --update-schema.
""",
)
@cloup.option(
"--discover-missing",
help="Discover resources in the cluster that don't have wrapper classes",
Expand Down Expand Up @@ -555,6 +607,20 @@ def handle_test_generation(add_tests: bool) -> None:
"regenerate_all",
],
)
@cloup.constraint(
mutually_exclusive,
["update_schema", "update_schema_for"],
)
@cloup.constraint(
If(IsSet("update_schema_for"), then=accept_none),
[
"kind",
"discover_missing",
"coverage_report",
"generate_missing",
"regenerate_all",
],
)
@cloup.constraint(
If(IsSet("backup"), then=require_one),
["regenerate_all", "overwrite"],
Expand All @@ -577,6 +643,7 @@ def main(
filter: str | None,
json_output: bool,
update_schema: bool,
update_schema_for: str | None,
verbose: bool,
) -> None:
"""Generate Python module for K8S resource."""
Expand Down Expand Up @@ -610,13 +677,18 @@ def main(
validate_actions(
kind=kind,
update_schema=update_schema,
update_schema_for=update_schema_for,
discover_missing=discover_missing,
coverage_report=coverage_report,
generate_missing=generate_missing,
regenerate_all=regenerate_all,
)

# Handle schema update
# Handle single resource schema update (if specified)
if not handle_single_schema_update(update_schema_for=update_schema_for):
return

# Handle full schema update
if not handle_schema_update(update_schema=update_schema, generate_missing=generate_missing):
return

Expand Down
Loading