Skip to content

{AKS}: add sreclaw to spin up openclaw to SRE AKS clusters#9664

Open
mainred wants to merge 2 commits intoAzure:mainfrom
mainred:sreclaw-aks-preview
Open

{AKS}: add sreclaw to spin up openclaw to SRE AKS clusters#9664
mainred wants to merge 2 commits intoAzure:mainfrom
mainred:sreclaw-aks-preview

Conversation

@mainred
Copy link
Member

@mainred mainred commented Mar 10, 2026


This checklist is used to make sure that common guidelines for a pull request are followed.

Related command

General Guidelines

  • Have you run azdev style <YOUR_EXT> locally? (pip install azdev required)
  • Have you run python scripts/ci/test_index.py -q locally? (pip install wheel==0.30.0 required)
  • My extension version conforms to the Extension version schema

For new extensions:

About Extension Publish

There is a pipeline to automatically build, upload and publish extension wheels.
Once your pull request is merged into main branch, a new pull request will be created to update src/index.json automatically.
You only need to update the version information in file setup.py and historical information in file HISTORY.rst in your PR but do not modify src/index.json.

@mainred mainred requested a review from andyliuliming as a code owner March 10, 2026 09:33
Copilot AI review requested due to automatic review settings March 10, 2026 09:33
@mainred mainred requested a review from FumingZhang as a code owner March 10, 2026 09:33
@azure-client-tools-bot-prd
Copy link

azure-client-tools-bot-prd bot commented Mar 10, 2026

⚠️Azure CLI Extensions Breaking Change Test
⚠️aks-preview
rule cmd_name rule_message suggest_message
⚠️ 1011 - SubgroupAdd aks sreclaw sub group aks sreclaw added

@azure-client-tools-bot-prd
Copy link

Hi @mainred,
Please write the description of changes which can be perceived by customers into HISTORY.rst.
If you want to release a new extension version, please update the version in setup.py as well.

@yonzhan
Copy link
Collaborator

yonzhan commented Mar 10, 2026

Thank you for your contribution! We will review the pull request and get back to you soon.

@github-actions
Copy link
Contributor

The git hooks are available for azure-cli and azure-cli-extensions repos. They could help you run required checks before creating the PR.

Please sync the latest code with latest dev branch (for azure-cli) or main branch (for azure-cli-extensions).
After that please run the following commands to enable git hooks:

pip install azdev --upgrade
azdev setup -c <your azure-cli repo path> -r <your azure-cli-extensions repo path>

@github-actions
Copy link
Contributor

CodeGen Tools Feedback Collection

Thank you for using our CodeGen tool. We value your feedback, and we would like to know how we can improve our product. Please take a few minutes to fill our codegen survey

@github-actions
Copy link
Contributor

Hi @mainred

Release Suggestions

Module: aks-preview

  • Please log updates into to src/aks-preview/HISTORY.rst
  • Update VERSION to 19.0.0b25 in src/aks-preview/setup.py

Notes

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a new aks sreclaw command group to the aks-preview Azure CLI extension to install the sreclaw operator, create an OpenClawInstance custom resource, and port-forward to the resulting service.

Changes:

  • Add aks sreclaw enable/create/connect commands and implement their logic in custom.py.
  • Wire up command registration, parameters, and help content for the new command group.
  • Add a kubernetes Python dependency to support direct Kubernetes API interactions.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
src/aks-preview/setup.py Adds kubernetes to extension dependencies.
src/aks-preview/azext_aks_preview/custom.py Implements sreclaw enable/create/connect (K8s API + Helm + port-forward).
src/aks-preview/azext_aks_preview/commands.py Registers the new aks sreclaw command group.
src/aks-preview/azext_aks_preview/_params.py Adds CLI parameters for the sreclaw commands.
src/aks-preview/azext_aks_preview/_help.py Adds help text and examples for aks sreclaw.
scripts/ci/test_source.py Modifies CI test execution behavior and wheel build error handling.

Comment on lines +5415 to +5423
def aks_sreclaw_enable(
cmd, # pylint: disable=unused-argument
client,
resource_group_name,
name,
namespace,
litellm_master_key,
):
"""Enable the sreclaw operator on an AKS cluster via Helm."""
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

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

New aks sreclaw commands introduce substantial behavior (namespace/secret creation, Helm install, CR creation, port-forwarding) but there are no corresponding tests under azext_aks_preview/tests/latest. Add unit tests that mock the Kubernetes client and subprocess.run to validate success and error paths (e.g., namespace missing, secret exists vs create, Helm failure).

Copilot uses AI. Check for mistakes.
Comment on lines +5431 to +5446
# Fetch admin kubeconfig and write to a temp file
credential_results = client.list_cluster_admin_credentials(
resource_group_name, name
)
if not credential_results or not credential_results.kubeconfigs:
raise CLIError("No Kubernetes admin credentials found.")

kubeconfig_data = credential_results.kubeconfigs[0].value.decode("utf-8")
kubeconfig_fd, kubeconfig_path = tempfile.mkstemp(suffix=".kubeconfig")
try:
with os.fdopen(kubeconfig_fd, "w") as f:
f.write(kubeconfig_data)

# Initialize Kubernetes client from the admin kubeconfig
k8s_config.load_kube_config(config_file=kubeconfig_path)
core_v1 = k8s_client.CoreV1Api()
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

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

The kubeconfig fetch/write/load logic is duplicated across aks_sreclaw_enable, aks_sreclaw_create, and aks_sreclaw_connect. Consider extracting this into a small helper (e.g., context manager that yields a kubeconfig path) to reduce maintenance cost and ensure cleanup/error handling stays consistent.

Copilot uses AI. Check for mistakes.
Comment on lines +26 to +28
DEPENDENCIES = [
"kubernetes>=24.2.0",
]
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

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

DEPENDENCIES now adds a runtime dependency, but the extension version and HISTORY entry were not updated as part of this change. For Azure CLI extension publishing, dependency changes should be accompanied by a version bump and a corresponding HISTORY.rst entry so users can pick up the new wheel and understand why the dependency changed.

Copilot uses AI. Check for mistakes.
Comment on lines +70 to +71
if ext_name != "aks-agent":
continue
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

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

This change short-circuits CI extension testing to only run when ext_name == "aks-agent", which will skip tests for all other edited extensions (including aks-preview) and can mask regressions. If the goal is to narrow scope, consider filtering based on the existing edited-extension detection logic (commit range / PR diff) rather than hard-coding a single extension name.

Suggested change
if ext_name != "aks-agent":
continue

Copilot uses AI. Check for mistakes.
check_output(['python', 'setup.py', 'bdist_wheel', '-q', '-d', built_whl_dir], cwd=s)
except CalledProcessError as err:
raise("Unable to build extension {} : {}".format(s, err))
raise ("Unable to build extension {} : {}".format(s, err))
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

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

raise ("Unable to build extension ...") attempts to raise a string, which is a TypeError in Python 3 and will hide the original CalledProcessError. Raise an exception type/instance (e.g., RuntimeError) and chain the original error with from err so the failure is actionable in CI logs.

Suggested change
raise ("Unable to build extension {} : {}".format(s, err))
raise RuntimeError("Unable to build extension {} : {}".format(s, err)) from err

Copilot uses AI. Check for mistakes.
examples:
- name: Port-forward the sreclaw service for alias alice
text: |-
az aks sreclaw connect --resource-group myResourceGroup --name myAKSCluster --alias alice - name: Port-forward on a custom local port
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

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

The help examples YAML is malformed here: the first example line contains the start of the next - name: entry on the same line, which will break help rendering/parsing. Split the examples into two separate properly-indented entries.

Suggested change
az aks sreclaw connect --resource-group myResourceGroup --name myAKSCluster --alias alice - name: Port-forward on a custom local port
az aks sreclaw connect --resource-group myResourceGroup --name myAKSCluster --alias alice
- name: Port-forward on a custom local port

Copilot uses AI. Check for mistakes.
Comment on lines +5513 to +5517
result = subprocess.run( # pylint: disable=subprocess-run-check
helm_args,
capture_output=True,
text=True,
env=env,
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

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

subprocess.run(..., capture_output=True, text=True) requires Python 3.7+ (capture_output/text are not available in 3.6). Since this extension currently declares Python 3.6 support in setup.py classifiers, this will fail at runtime on 3.6. Either switch to stdout=PIPE, stderr=PIPE, universal_newlines=True for compatibility, or update the supported Python versions/classifiers accordingly.

Copilot uses AI. Check for mistakes.
Comment on lines +5721 to +5723
cfg = Configuration.get_default_copy()
cfg.assert_hostname = False
Configuration.set_default(cfg)
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

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

cfg.assert_hostname = False disables hostname verification for the Kubernetes API client, weakening TLS protections. If this is required for port-forwarding, it should be narrowly scoped/justified; otherwise prefer leaving hostname verification enabled (or only disabling it when explicitly requested via a flag).

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AKS Auto-Assign Auto assign by bot

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants