ibee-cli 0.4.0__tar.gz → 0.4.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ibee_cli-0.4.0/src/ibee_cli.egg-info → ibee_cli-0.4.1}/PKG-INFO +9 -2
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/README.md +7 -0
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/pyproject.toml +2 -2
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/src/ibee_cli/__init__.py +1 -1
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/src/ibee_cli/commands/gpus.py +1 -1
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/src/ibee_cli/commands/vms.py +1 -1
- {ibee_cli-0.4.0 → ibee_cli-0.4.1/src/ibee_cli.egg-info}/PKG-INFO +9 -2
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/src/ibee_cli.egg-info/requires.txt +1 -1
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/tests/test_billing_preflight.py +39 -1
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/tests/test_cli.py +1 -1
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/LICENSE +0 -0
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/setup.cfg +0 -0
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/src/ibee_cli/commands/__init__.py +0 -0
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/src/ibee_cli/commands/billing.py +0 -0
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/src/ibee_cli/commands/block_storage.py +0 -0
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/src/ibee_cli/commands/buckets.py +0 -0
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/src/ibee_cli/commands/cdn.py +0 -0
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/src/ibee_cli/commands/compute.py +0 -0
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/src/ibee_cli/commands/console.py +0 -0
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/src/ibee_cli/commands/firewalls.py +0 -0
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/src/ibee_cli/commands/load_balancers.py +0 -0
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/src/ibee_cli/commands/networking.py +0 -0
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/src/ibee_cli/commands/ops.py +0 -0
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/src/ibee_cli/commands/reserved_ips.py +0 -0
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/src/ibee_cli/commands/secrets.py +0 -0
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/src/ibee_cli/commands/vm_lifecycle.py +0 -0
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/src/ibee_cli/context.py +0 -0
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/src/ibee_cli/helpers.py +0 -0
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/src/ibee_cli/main.py +0 -0
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/src/ibee_cli/render.py +0 -0
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/src/ibee_cli.egg-info/SOURCES.txt +0 -0
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/src/ibee_cli.egg-info/dependency_links.txt +0 -0
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/src/ibee_cli.egg-info/entry_points.txt +0 -0
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/src/ibee_cli.egg-info/top_level.txt +0 -0
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/tests/test_block_storage_cdn_commands.py +0 -0
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/tests/test_cloud_vm_commands.py +0 -0
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/tests/test_foundations.py +0 -0
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/tests/test_networking_commands.py +0 -0
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/tests/test_networking_parity_commands.py +0 -0
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/tests/test_object_storage_commands.py +0 -0
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/tests/test_parity_alignment.py +0 -0
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/tests/test_review_fixes.py +0 -0
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/tests/test_secret_store_commands.py +0 -0
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/tests/test_vm_lifecycle_commands.py +0 -0
- {ibee_cli-0.4.0 → ibee_cli-0.4.1}/tests/test_vm_parity_commands.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ibee-cli
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.1
|
|
4
4
|
Summary: Official command-line interface for the IBEE Solutions cloud platform
|
|
5
5
|
Author-email: IBEE Solutions <support@ibee.ai>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -13,7 +13,7 @@ Classifier: Environment :: Console
|
|
|
13
13
|
Requires-Python: >=3.10
|
|
14
14
|
Description-Content-Type: text/markdown
|
|
15
15
|
License-File: LICENSE
|
|
16
|
-
Requires-Dist: ibee<0.5.0,>=0.4.
|
|
16
|
+
Requires-Dist: ibee<0.5.0,>=0.4.1
|
|
17
17
|
Requires-Dist: httpx>=0.27
|
|
18
18
|
Requires-Dist: typer>=0.12
|
|
19
19
|
Requires-Dist: click>=8.1
|
|
@@ -315,6 +315,13 @@ before a billable create: the create is sent only when billing answers
|
|
|
315
315
|
guidance when adding credits in the portal can resolve it) and the command
|
|
316
316
|
exits 1. The preflight never reserves funds.
|
|
317
317
|
|
|
318
|
+
For Cloud/GPU VM creates, `--check-billing` / `--preflight-billing` checks Billing's
|
|
319
|
+
account status only. No SKU-only monthly probe or client-calculated price is
|
|
320
|
+
sent. The selected catalog term goes to the create API, where the upstream
|
|
321
|
+
catalog quote and Billing decide affordability before provisioning. A passing
|
|
322
|
+
preflight is not purchase approval. CLI 0.4.1 requires Python SDK 0.4.1 or later;
|
|
323
|
+
the CLI delegates to it and does not implement its own pricing policy.
|
|
324
|
+
|
|
318
325
|
Load balancers take backends, routing, policy, health checks and L7 rules either
|
|
319
326
|
as flags (`--backend TYPE:TARGET:PORT[:WEIGHT][:tls]`, `--rule
|
|
320
327
|
PRIORITY:PATH_PREFIX[:HEADER=VALUE]`, ...) or as JSON (`--backends`, `--routing`,
|
|
@@ -290,6 +290,13 @@ before a billable create: the create is sent only when billing answers
|
|
|
290
290
|
guidance when adding credits in the portal can resolve it) and the command
|
|
291
291
|
exits 1. The preflight never reserves funds.
|
|
292
292
|
|
|
293
|
+
For Cloud/GPU VM creates, `--check-billing` / `--preflight-billing` checks Billing's
|
|
294
|
+
account status only. No SKU-only monthly probe or client-calculated price is
|
|
295
|
+
sent. The selected catalog term goes to the create API, where the upstream
|
|
296
|
+
catalog quote and Billing decide affordability before provisioning. A passing
|
|
297
|
+
preflight is not purchase approval. CLI 0.4.1 requires Python SDK 0.4.1 or later;
|
|
298
|
+
the CLI delegates to it and does not implement its own pricing policy.
|
|
299
|
+
|
|
293
300
|
Load balancers take backends, routing, policy, health checks and L7 rules either
|
|
294
301
|
as flags (`--backend TYPE:TARGET:PORT[:WEIGHT][:tls]`, `--rule
|
|
295
302
|
PRIORITY:PATH_PREFIX[:HEADER=VALUE]`, ...) or as JSON (`--backends`, `--routing`,
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ibee-cli"
|
|
7
|
-
version = "0.4.
|
|
7
|
+
version = "0.4.1"
|
|
8
8
|
description = "Official command-line interface for the IBEE Solutions cloud platform"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
@@ -18,7 +18,7 @@ classifiers = [
|
|
|
18
18
|
"Environment :: Console",
|
|
19
19
|
]
|
|
20
20
|
dependencies = [
|
|
21
|
-
"ibee>=0.4.
|
|
21
|
+
"ibee>=0.4.1,<0.5.0",
|
|
22
22
|
"httpx>=0.27",
|
|
23
23
|
"typer>=0.12",
|
|
24
24
|
"click>=8.1",
|
|
@@ -151,7 +151,7 @@ def create_gpu_vm(
|
|
|
151
151
|
preflight: bool = typer.Option(
|
|
152
152
|
False,
|
|
153
153
|
"--preflight-billing",
|
|
154
|
-
help="Check
|
|
154
|
+
help="Check Billing account status first; upstream create decides affordability (same as --check-billing)",
|
|
155
155
|
),
|
|
156
156
|
wait: bool = typer.Option(False, "--wait", help="Poll until the VM is provisioned"),
|
|
157
157
|
timeout: Optional[float] = timeout_option(),
|
|
@@ -150,7 +150,7 @@ def create_vm(
|
|
|
150
150
|
preflight: bool = typer.Option(
|
|
151
151
|
False,
|
|
152
152
|
"--preflight-billing",
|
|
153
|
-
help="Check
|
|
153
|
+
help="Check Billing account status first; upstream create decides affordability (same as --check-billing)",
|
|
154
154
|
),
|
|
155
155
|
wait: bool = typer.Option(False, "--wait", help="Poll until the VM is provisioned"),
|
|
156
156
|
timeout: Optional[float] = timeout_option(),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ibee-cli
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.1
|
|
4
4
|
Summary: Official command-line interface for the IBEE Solutions cloud platform
|
|
5
5
|
Author-email: IBEE Solutions <support@ibee.ai>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -13,7 +13,7 @@ Classifier: Environment :: Console
|
|
|
13
13
|
Requires-Python: >=3.10
|
|
14
14
|
Description-Content-Type: text/markdown
|
|
15
15
|
License-File: LICENSE
|
|
16
|
-
Requires-Dist: ibee<0.5.0,>=0.4.
|
|
16
|
+
Requires-Dist: ibee<0.5.0,>=0.4.1
|
|
17
17
|
Requires-Dist: httpx>=0.27
|
|
18
18
|
Requires-Dist: typer>=0.12
|
|
19
19
|
Requires-Dist: click>=8.1
|
|
@@ -315,6 +315,13 @@ before a billable create: the create is sent only when billing answers
|
|
|
315
315
|
guidance when adding credits in the portal can resolve it) and the command
|
|
316
316
|
exits 1. The preflight never reserves funds.
|
|
317
317
|
|
|
318
|
+
For Cloud/GPU VM creates, `--check-billing` / `--preflight-billing` checks Billing's
|
|
319
|
+
account status only. No SKU-only monthly probe or client-calculated price is
|
|
320
|
+
sent. The selected catalog term goes to the create API, where the upstream
|
|
321
|
+
catalog quote and Billing decide affordability before provisioning. A passing
|
|
322
|
+
preflight is not purchase approval. CLI 0.4.1 requires Python SDK 0.4.1 or later;
|
|
323
|
+
the CLI delegates to it and does not implement its own pricing policy.
|
|
324
|
+
|
|
318
325
|
Load balancers take backends, routing, policy, health checks and L7 rules either
|
|
319
326
|
as flags (`--backend TYPE:TARGET:PORT[:WEIGHT][:tls]`, `--rule
|
|
320
327
|
PRIORITY:PATH_PREFIX[:HEADER=VALUE]`, ...) or as JSON (`--backends`, `--routing`,
|
|
@@ -7,7 +7,7 @@ from types import SimpleNamespace
|
|
|
7
7
|
import pytest
|
|
8
8
|
from typer.testing import CliRunner
|
|
9
9
|
|
|
10
|
-
from ibee_cli.commands import billing, secrets
|
|
10
|
+
from ibee_cli.commands import billing, secrets, vm_lifecycle, vms, gpus
|
|
11
11
|
from ibee_cli.main import app
|
|
12
12
|
|
|
13
13
|
import _net_fixtures as _net
|
|
@@ -59,6 +59,44 @@ def test_manual_billing_command_reports_old_sdk(monkeypatch):
|
|
|
59
59
|
assert "Upgrade the SDK" in result.output
|
|
60
60
|
|
|
61
61
|
|
|
62
|
+
@pytest.mark.parametrize("group,family", [("vms", "cloud"), ("gpus", "gpu")])
|
|
63
|
+
@pytest.mark.parametrize("denied", [False, True])
|
|
64
|
+
def test_vm_preflight_uses_upstream_status_and_preserves_create_denial(gw, monkeypatch, group, family, denied):
|
|
65
|
+
for module in (vm_lifecycle, vms, gpus):
|
|
66
|
+
monkeypatch.setattr(module, "get_client", lambda _settings: gw.client())
|
|
67
|
+
gw.on("GET", "compute/plans", {"plans": [{
|
|
68
|
+
"plan_id": "plan", "vm_type": family, "selectable": True, "pricing_status": "priced",
|
|
69
|
+
"cpu": 2, "ram_mb": 4096, "disk_gb": 50, "gpu_count": 1, "gpu_model": "L4",
|
|
70
|
+
"billing_catalog": {"sku_id": 1, "sku_code": "VM-1", "billing_options": [
|
|
71
|
+
{"billing_interval": "HOURLY", "unit_price_minor": 3500, "committed": False},
|
|
72
|
+
]},
|
|
73
|
+
}]})
|
|
74
|
+
gw.on("GET", "compute/images", {"images": [{
|
|
75
|
+
"template_id": "image", "os_type": "linux", "os_distro": "ubuntu",
|
|
76
|
+
"gpu_compatible": True, "compatible_vm_types": [family], "site_ids": [],
|
|
77
|
+
}]})
|
|
78
|
+
gw.on("POST", "billing/resource-eligibility", {
|
|
79
|
+
"organization_id": "org", "allowed": True, "reason": "status_only",
|
|
80
|
+
"effective_balance_minor": 3500,
|
|
81
|
+
})
|
|
82
|
+
response = (402, {"error": "billing_denied", "billing_reason": "insufficient_balance",
|
|
83
|
+
"billing_sku_code": "VM-1", "admission_context_id": "adm_upstream"}) if denied else (202, {
|
|
84
|
+
"operation_id": "op_65f0c0ffee0000000000abcd", "vm_id": "65f0c0ffee0000000000abcd",
|
|
85
|
+
"status": "accepted", "submitted_at": "2026-09-29T00:00:00Z",
|
|
86
|
+
})
|
|
87
|
+
gw.on("POST", f"compute/{family}-vms", response)
|
|
88
|
+
result = runner.invoke(app, [*BASE_ARGS, "--check-billing", group, "create", "test",
|
|
89
|
+
"--site-id", "site-1", "--plan-id", "plan", "--template-id", "image",
|
|
90
|
+
"--billing-term", "HOURLY"])
|
|
91
|
+
assert result.exit_code == (1 if denied else 0), result.output
|
|
92
|
+
assert gw.last("POST", "billing/resource-eligibility").json == {}
|
|
93
|
+
creates = [c for c in gw.calls if c.method == "POST" and c.path == f"compute/{family}-vms"]
|
|
94
|
+
assert len(creates) == 1
|
|
95
|
+
assert creates[0].json["billing_catalog"]["billing_interval"] == "HOURLY"
|
|
96
|
+
if denied:
|
|
97
|
+
assert "balance" in result.output.lower()
|
|
98
|
+
|
|
99
|
+
|
|
62
100
|
@pytest.mark.parametrize(
|
|
63
101
|
("args", "script", "post_path"),
|
|
64
102
|
[
|
|
@@ -37,7 +37,7 @@ def test_help_lists_command_groups():
|
|
|
37
37
|
def test_version():
|
|
38
38
|
result = runner.invoke(app, ["--version"])
|
|
39
39
|
assert result.exit_code == 0
|
|
40
|
-
assert "ibee-cli 0.4.
|
|
40
|
+
assert "ibee-cli 0.4.1" in result.output
|
|
41
41
|
|
|
42
42
|
|
|
43
43
|
def test_subcommand_help():
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|