Skip to content

Register crud module in pyproject.toml - #1231

Open
Diamond (diamondpowell) wants to merge 14 commits into
mainfrom
dipowell/register-crud-package
Open

Register crud module in pyproject.toml#1231
Diamond (diamondpowell) wants to merge 14 commits into
mainfrom
dipowell/register-crud-package

Conversation

@diamondpowell

@diamondpowell Diamond (diamondpowell) commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Summary

Registers the open-source CRUD module as part of the telescope-benchmarks Python package so callers can install and run CRUD operations without source-tree PYTHONPATH routing.

Why

The internal Telescope CRUD migration now uses the open-source Python CRUD module as the source of truth for node-pool and workload operations. This PR provides the package contract required by that migration: installable modules, runtime workload manifests, a CLI entry point, and explicit pipeline authentication and cluster selection inputs.

Changes

  • Register crud, crud.azure, and crud.aws in pyproject.toml.
  • Add the telescope-crud console entry point.
  • Include deployment, Job, and StatefulSet YAML manifests in the installed package.
  • Add exclude_managed_identity support to AKSClient and expose it as an opt-in CRUD CLI flag.
  • Add optional AKS cluster-name selection while preserving discovery when omitted.
  • Preserve the existing positional NodePoolCRUD constructor contract.
  • Add focused tests for authentication behavior and constructor compatibility.

Related PR

Internal migration: ADO PR 16193735

The two PRs are separated by ownership boundary:

  • This PR owns the reusable open-source Python package and runtime contract.
  • The internal PR owns pipeline orchestration, cloud login, resource validation, result publication, and production rollout.

The internal PR is intentionally open as this package's integration consumer. It shows reviewers how the package is installed and invoked, so review of both PRs can happen in parallel. The internal PR does not need to merge before this package PR.

The internal validation pipeline cloned this draft branch directly and installed modules/python with pip. Draft status does not affect branch installation as long as the branch is pushed.

Validation

  • 100 focused CRUD and AKS client unit tests passed before pipeline validation.
  • 81 focused CRUD tests passed after the constructor-compatibility fix.
  • Python Validation: passed.
  • YAML Validation: passed.
  • CLA: passed.
  • Feature-to-feature pip-install validation: ADO build 177409535.
    • Five of five Azure regions passed: westcentralus, westus2, eastasia, eastus2euap, and centraluseuap.
    • No failed or canceled records.
    • Internal commit: c18584d6.
    • Open-source package commit: 3e335184.

Review and Merge Sequence

  1. Review this package PR and internal PR #16193735 in parallel.
  2. Merge this package PR first. Package registration remains separate and is not blocked on workload timing.
  3. Review and merge the planned workload-timing PR against the updated open-source main.
  4. Revalidate the already-reviewed internal migration against the resulting open-source main from a disposable validation branch.
  5. Merge internal PR #16193735 last, after required workload telemetry and consumer compatibility pass.
  6. Run a post-merge production smoke test and validate ADX output.

Final Follow-up Validation

  • Final open-source commit: 9f96c3e0.
  • 123 focused tests passed after the VirtualMachines scale-state, exit-code, and helper/test extraction changes.
  • Pylint: 10.00/10.
  • Final file sizes: aks_client.py 974 lines, test_aks_client.py 838 lines, and test_main.py 1564 lines.
  • Targeted VirtualMachines lifecycle: ADO build 177546874.
    • Internal test commit: 00c99b90.
    • Open-source package commit: 9f96c3e0.
    • Create, scale up, Deployment, StatefulSet, Job, scale down, delete, collect, upload, and cleanup all passed.
    • No failed, canceled, or succeeded-with-issues records.

Build 177409535 remains the five-region VMSS installation validation; build 177546874 is the targeted VirtualMachines validation.

Final Authoritative Multi-Region Validation

  • Final Build: ADO build 177701638 (Aug 21, 2026)
  • Commits: Internal test commit b9460721 and open-source tested commit 9f96c3e0. Internal cleanup commit 3730f654 restored new-pipeline-test.yml (cleanup commit itself was not tested by build).
  • Regions: westcentralus, westus2, eastasia, eastus2euap, and centraluseuap. Both small VMSS and VirtualMachines cases ran in every region; 5/5 stages and 10/10 matrix jobs passed.
  • Scope: Package install, create, scale up, Deployment, StatefulSet, Job, scale down, delete, collect/upload/cleanup passed.
  • Status: No failed, canceled, abandoned, or succeeded-with-issues records.
  • Distinction: Clearly retain build 177409535 as earlier five-region VMSS package-installation evidence and build 177546874 as earlier one-region targeted VirtualMachines evidence; do not call either final-head all-type regional evidence.

Add crud to packages list and telescope-crud entry point.
Enables pip install telescope-benchmarks to include CRUD module.
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown

For reviewers only: reply /run-tf-integration to trigger the terraform integration pipeline before approving the PR.

crud/azure was missing __init__.py, and crud.azure and crud.aws
sub-packages were not listed in pyproject.toml packages. After
pip install, imports like 'from crud.azure.node_pool_crud import
NodePoolCRUD' would fail with ModuleNotFoundError.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR makes the crud module installable as part of the telescope-benchmarks Python package and exposes it via a telescope-crud console entry point, while extending Azure CRUD plumbing to support explicit AKS cluster selection and optionally excluding managed identity from the Azure credential chain.

Changes:

  • Package registration: add crud (and subpackages) to pyproject.toml, include workload manifest templates as package data, and add the telescope-crud entry point.
  • Azure auth + selection: plumb cluster_name and exclude_managed_identity from CLI → NodePoolCRUDAKSClient (DefaultAzureCredential).
  • Tests: add focused unit tests for the new credential-chain behavior and to ensure positional constructor compatibility.

Reviewed changes

Copilot reviewed 6 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
modules/python/pyproject.toml Registers crud packages, includes workload template YAMLs, and adds telescope-crud console script.
modules/python/crud/main.py Adds --cluster-name and --exclude-managed-identity CLI flags and passes them into Azure NodePoolCRUD.
modules/python/crud/azure/node_pool_crud.py Extends NodePoolCRUD constructor to accept and forward cluster_name / exclude_managed_identity.
modules/python/clients/aks_client.py Adds exclude_managed_identity to optionally exclude ManagedIdentityCredential from DefaultAzureCredential.
modules/python/tests/crud/test_azure_node_pool_crud.py Adds unit tests validating auth configuration defaults and positional-arg compatibility.
modules/python/tests/clients/test_aks_client.py Adds tests for DefaultAzureCredential default behavior vs. excluding managed identity.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread modules/python/crud/main.py Outdated
return ready_nodes


def instrument_aks_nodepool_provisioning(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see why we need this extra wrapper. The name is so close to instrument_nodepool_provisioning and this makes people confused. I don't see how this help generalize our codes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added the wrapper when I added VirtualMachines support because the new path uses an Azure CLI callable while the existing VMSS path uses the SDK. I needed both operations to use the same ARM and Kubernetes readiness instrumentation.

Looking at the resulting call chain, I agree that the wrapper does not provide enough separation to justify another similarly named function. I removed it. AKSClient now builds the Kubernetes readiness callable and passes it, along with the prepared ARM callable, directly to instrument_nodepool_provisioning.

if node_pool_type != "VirtualMachines":
parameters["count"] = node_count
parameters["vm_size"] = vm_size
return None

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is the code smell:
Line 144 returns None but also mutate the parameters secretly, while line 147 returns a function. Check the call site - the None value of arm_callable is passed through but eventually fallback to begin_create_or_update_with_retry within provisioning_instrumentation.py.

How about something like this:

def prepare_create_operation(
    parameters, node_pool_type, gpu_node_pool,
    resource_group, cluster_name, node_pool_name, node_count, vm_size,
    *, aks_client, k8s_client=None,  # whatever the SDK callable needs
):
    """Return a zero-arg ARM callable for the create, dispatched by pool type."""
    if node_pool_type == "VirtualMachines":
        if gpu_node_pool:
            raise ValueError("GPU node pools with type VirtualMachines are not supported")
        return partial(
            create_virtual_machines_node_pool,
            resource_group, cluster_name, node_pool_name, node_count, vm_size,
        )
    # VMSS: still the SDK path, but returned as a callable instead of a None+mutation
    parameters = {**parameters, "count": node_count, "vm_size": vm_size}
    return partial(begin_create_or_update_with_retry,
                   aks_client, resource_group, cluster_name, node_pool_name, parameters)

to make it always return a callable.

The same reasoning can apply to def prepare_scale_operation below

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that returning either None or a callable makes the contract difficult to follow. I originally used None to preserve the existing VMSS fallback while I added the VirtualMachines CLI path. I did not realize until your comment that this split the final operation selection between the preparation helper and the instrumentation wrapper.

I updated both prepare_create_operation and prepare_scale_operation to always return a zero-argument ARM callable. VMSS now returns a callable around begin_create_or_update_with_retry, while VirtualMachines returns the Azure CLI callable.

I also moved the GPU profile setup before the VMSS parameter copy and preserved the progressive-scale label. The tests now execute the VMSS callables and verify the SDK payloads, including progressive counts [2, 3].

Comment thread modules/python/clients/aks_client.py Outdated
enable_managed_gpu: bool = False,
gpu_instance_profile: Optional[str] = None,
gpu_mig_strategy: Optional[str] = None,
node_pool_type: str = "VirtualMachineScaleSets",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make VirtualMachineScaleSets as constant? I see multiple places where we have this hard-coded string.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that this value should not be repeated across the different layers. I added AzureNodePoolTypeConstants.VIRTUAL_MACHINE_SCALE_SETS and used it for the production defaults and comparisons in AKSClient, Azure NodePoolCRUD, and the CLI dispatch.


def get_node_pool_scale_state(node_pool, node_pool_type):
"""Return current node count and VM size for VMSS or VirtualMachines pools."""
if node_pool_type != "VirtualMachines":

@liyu-ma Liyu Ma (liyu-ma) Aug 24, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make VirtualMachines as constant? Can you inspect all occurrences of this hard-coded str from this PR and update them

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked all occurrences of the hard-coded VirtualMachines value in my changes. I replaced the production comparisons, defaults, and Azure command construction with AzureNodePoolTypeConstants.VIRTUAL_MACHINES.

I kept the literal in error messages, docstrings, and the test that verifies the exact Azure CLI command because those are user-facing text or external-contract assertions.

Comment thread modules/python/crud/main.py Outdated
**azure_kwargs,
}
if args.cloud == "azure":
create_kwargs["node_pool_type"] = args.node_pool_type

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are many occurences like line131-132. You can just fold this to

azure_kwargs = {
    "gpu_instance_profile": args.gpu_instance_profile,
    "gpu_mig_strategy": args.gpu_mig_strategy,
    "node_pool_type": args.node_pool_type,
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that node_pool_type belongs with the other Azure-only arguments. I added it to the shared azure_kwargs dictionary and removed the repeated assignments from the create, scale, and all branches.

I scoped the dictionary to those three commands because delete uses the same handler but does not define node_pool_type, gpu_instance_profile, or gpu_mig_strategy. This keeps the shared construction without breaking Azure delete or forwarding Azure-only arguments to AWS.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants