fdai-deployment-cli 0.1.2__py3-none-any.whl
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.
- fdai_deployment_cli/__about__.py +3 -0
- fdai_deployment_cli/__init__.py +5 -0
- fdai_deployment_cli/__main__.py +5 -0
- fdai_deployment_cli/acr_publish.py +585 -0
- fdai_deployment_cli/aks_catalog_review.py +137 -0
- fdai_deployment_cli/aks_historical_reconciliation.py +732 -0
- fdai_deployment_cli/aks_job_environment.py +59 -0
- fdai_deployment_cli/aks_job_execution.py +794 -0
- fdai_deployment_cli/aks_kubernetes_defaults.py +66 -0
- fdai_deployment_cli/aks_preflight.py +422 -0
- fdai_deployment_cli/aks_readiness.py +220 -0
- fdai_deployment_cli/aks_service_update.py +180 -0
- fdai_deployment_cli/aks_workload_jobs.py +281 -0
- fdai_deployment_cli/application_state_adoption.py +347 -0
- fdai_deployment_cli/azure_actor.py +61 -0
- fdai_deployment_cli/azure_naming.py +252 -0
- fdai_deployment_cli/azure_retail_prices.py +173 -0
- fdai_deployment_cli/bootstrap_approval.py +99 -0
- fdai_deployment_cli/bootstrap_channel.py +321 -0
- fdai_deployment_cli/bootstrap_executor.py +311 -0
- fdai_deployment_cli/bootstrap_plan.py +237 -0
- fdai_deployment_cli/bootstrap_reconcile.py +402 -0
- fdai_deployment_cli/bootstrap_support.py +138 -0
- fdai_deployment_cli/bootstrap_worker.py +448 -0
- fdai_deployment_cli/bundle.py +352 -0
- fdai_deployment_cli/capacity.py +143 -0
- fdai_deployment_cli/catalog_review_profile.py +306 -0
- fdai_deployment_cli/cli.py +798 -0
- fdai_deployment_cli/cli_help.py +214 -0
- fdai_deployment_cli/cli_parser.py +791 -0
- fdai_deployment_cli/cli_plan.py +450 -0
- fdai_deployment_cli/compiler.py +99 -0
- fdai_deployment_cli/console_artifact.py +218 -0
- fdai_deployment_cli/console_config.py +214 -0
- fdai_deployment_cli/console_update.py +832 -0
- fdai_deployment_cli/contracts.py +307 -0
- fdai_deployment_cli/control_package.py +140 -0
- fdai_deployment_cli/deadline_transport.py +70 -0
- fdai_deployment_cli/deployment_cost.py +131 -0
- fdai_deployment_cli/deployment_deadline.py +28 -0
- fdai_deployment_cli/deployment_kit.py +790 -0
- fdai_deployment_cli/deployment_kit_cache.py +191 -0
- fdai_deployment_cli/deployment_progress.py +648 -0
- fdai_deployment_cli/development_authority_cli.py +56 -0
- fdai_deployment_cli/development_authority_profile.py +319 -0
- fdai_deployment_cli/doctor.py +136 -0
- fdai_deployment_cli/entitlement_preflight.py +68 -0
- fdai_deployment_cli/entitlement_transport.py +49 -0
- fdai_deployment_cli/entra_bootstrap.py +579 -0
- fdai_deployment_cli/entra_control_profile.py +214 -0
- fdai_deployment_cli/entra_graph.py +349 -0
- fdai_deployment_cli/entra_profiles.py +215 -0
- fdai_deployment_cli/entra_source.py +244 -0
- fdai_deployment_cli/execution_bundle.py +478 -0
- fdai_deployment_cli/execution_copies.py +63 -0
- fdai_deployment_cli/foundation_adoption.py +438 -0
- fdai_deployment_cli/foundation_adoption_evidence.py +245 -0
- fdai_deployment_cli/foundation_adoption_host.py +157 -0
- fdai_deployment_cli/foundation_adoption_transport.py +51 -0
- fdai_deployment_cli/foundation_failure.py +72 -0
- fdai_deployment_cli/foundation_image.py +168 -0
- fdai_deployment_cli/foundation_input.py +235 -0
- fdai_deployment_cli/foundation_output.py +154 -0
- fdai_deployment_cli/foundation_plan.py +381 -0
- fdai_deployment_cli/foundation_process.py +64 -0
- fdai_deployment_cli/foundation_progress.py +231 -0
- fdai_deployment_cli/github_actions.py +171 -0
- fdai_deployment_cli/github_apply_artifact.py +259 -0
- fdai_deployment_cli/github_artifact_io.py +48 -0
- fdai_deployment_cli/github_dispatch.py +248 -0
- fdai_deployment_cli/github_plan_artifact.py +181 -0
- fdai_deployment_cli/github_provider_artifact.py +170 -0
- fdai_deployment_cli/github_transport.py +46 -0
- fdai_deployment_cli/github_workflow_values.py +312 -0
- fdai_deployment_cli/hub_image_deploy.py +354 -0
- fdai_deployment_cli/hub_image_stage.py +162 -0
- fdai_deployment_cli/hub_image_trust.py +281 -0
- fdai_deployment_cli/hub_ownership.py +161 -0
- fdai_deployment_cli/hub_workload_handoff.py +264 -0
- fdai_deployment_cli/hub_workload_handoff_inputs.py +227 -0
- fdai_deployment_cli/identity_profile.py +227 -0
- fdai_deployment_cli/image_targets.py +197 -0
- fdai_deployment_cli/installation_scope.py +280 -0
- fdai_deployment_cli/license.py +311 -0
- fdai_deployment_cli/license_issue.py +239 -0
- fdai_deployment_cli/lifecycle_authorization.py +252 -0
- fdai_deployment_cli/lifecycle_commands.py +173 -0
- fdai_deployment_cli/lifecycle_configuration.py +722 -0
- fdai_deployment_cli/lifecycle_configuration_artifact.py +45 -0
- fdai_deployment_cli/lifecycle_configuration_cli.py +324 -0
- fdai_deployment_cli/lifecycle_configuration_document.py +74 -0
- fdai_deployment_cli/lifecycle_configuration_entities.py +146 -0
- fdai_deployment_cli/lifecycle_configuration_package.py +492 -0
- fdai_deployment_cli/lifecycle_configuration_publication.py +277 -0
- fdai_deployment_cli/lifecycle_configuration_publication_cli.py +191 -0
- fdai_deployment_cli/lifecycle_configuration_sealing.py +127 -0
- fdai_deployment_cli/lifecycle_enrollment.py +45 -0
- fdai_deployment_cli/lifecycle_infrastructure_agent.py +174 -0
- fdai_deployment_cli/lifecycle_installation_binding.py +65 -0
- fdai_deployment_cli/lifecycle_native.py +247 -0
- fdai_deployment_cli/lifecycle_native_reconciliation.py +568 -0
- fdai_deployment_cli/lifecycle_native_transition.py +339 -0
- fdai_deployment_cli/lifecycle_ownership_exclusion.py +78 -0
- fdai_deployment_cli/lifecycle_plan.py +800 -0
- fdai_deployment_cli/lifecycle_promotion.py +185 -0
- fdai_deployment_cli/lifecycle_release.py +308 -0
- fdai_deployment_cli/lifecycle_self_upgrade.py +202 -0
- fdai_deployment_cli/lifecycle_upgrade_bundle.py +176 -0
- fdai_deployment_cli/notification_recipients_input.py +222 -0
- fdai_deployment_cli/observer_artifact.py +106 -0
- fdai_deployment_cli/oci_archive.py +353 -0
- fdai_deployment_cli/offline_kit.py +797 -0
- fdai_deployment_cli/offline_prepare.py +135 -0
- fdai_deployment_cli/operational_evidence_verifier_input.py +575 -0
- fdai_deployment_cli/plan_input.py +101 -0
- fdai_deployment_cli/private_output.py +192 -0
- fdai_deployment_cli/profile.py +70 -0
- fdai_deployment_cli/progress.py +183 -0
- fdai_deployment_cli/readiness.py +286 -0
- fdai_deployment_cli/run_command_receiver.py +418 -0
- fdai_deployment_cli/runtime_build.py +386 -0
- fdai_deployment_cli/runtime_profile.py +287 -0
- fdai_deployment_cli/runtime_release.py +745 -0
- fdai_deployment_cli/runtime_stage.py +82 -0
- fdai_deployment_cli/runtime_support_installation.py +215 -0
- fdai_deployment_cli/simulation.py +80 -0
- fdai_deployment_cli/source_application_inputs.py +397 -0
- fdai_deployment_cli/source_azure.py +586 -0
- fdai_deployment_cli/source_change_cli.py +107 -0
- fdai_deployment_cli/source_change_parser.py +75 -0
- fdai_deployment_cli/source_change_plan.py +181 -0
- fdai_deployment_cli/source_changed_update.py +196 -0
- fdai_deployment_cli/source_deploy.py +170 -0
- fdai_deployment_cli/source_foundation.py +174 -0
- fdai_deployment_cli/source_host_tools.py +163 -0
- fdai_deployment_cli/source_image_stage.py +400 -0
- fdai_deployment_cli/source_input.py +173 -0
- fdai_deployment_cli/source_projection.py +164 -0
- fdai_deployment_cli/source_receiver.py +76 -0
- fdai_deployment_cli/source_recovery.py +264 -0
- fdai_deployment_cli/source_runtime.py +81 -0
- fdai_deployment_cli/source_runtime_support.py +368 -0
- fdai_deployment_cli/source_service_update.py +726 -0
- fdai_deployment_cli/source_service_update_cli.py +47 -0
- fdai_deployment_cli/source_snapshot.py +178 -0
- fdai_deployment_cli/source_teardown.py +574 -0
- fdai_deployment_cli/source_terraform.py +85 -0
- fdai_deployment_cli/source_transport.py +399 -0
- fdai_deployment_cli/standalone_aks_inventory.py +558 -0
- fdai_deployment_cli/standalone_aks_job_execution.py +769 -0
- fdai_deployment_cli/standalone_aks_nodepool_guard.py +141 -0
- fdai_deployment_cli/standalone_application.py +977 -0
- fdai_deployment_cli/standalone_application_completion.py +151 -0
- fdai_deployment_cli/standalone_application_input_recovery.py +107 -0
- fdai_deployment_cli/standalone_application_recovery.py +116 -0
- fdai_deployment_cli/standalone_approval_input.py +24 -0
- fdai_deployment_cli/standalone_catalog_checkpoint.py +122 -0
- fdai_deployment_cli/standalone_catalog_review.py +251 -0
- fdai_deployment_cli/standalone_checkpoint_failure.py +127 -0
- fdai_deployment_cli/standalone_console_publish.py +174 -0
- fdai_deployment_cli/standalone_database_principals.py +41 -0
- fdai_deployment_cli/standalone_deploy.py +638 -0
- fdai_deployment_cli/standalone_development_authority.py +166 -0
- fdai_deployment_cli/standalone_foundation_adoption.py +87 -0
- fdai_deployment_cli/standalone_foundation_transition.py +767 -0
- fdai_deployment_cli/standalone_host.py +4608 -0
- fdai_deployment_cli/standalone_host_rebind.py +226 -0
- fdai_deployment_cli/standalone_host_residual.py +104 -0
- fdai_deployment_cli/standalone_host_state.py +145 -0
- fdai_deployment_cli/standalone_host_values.py +563 -0
- fdai_deployment_cli/standalone_kubernetes_tools.py +100 -0
- fdai_deployment_cli/standalone_license_installation.py +177 -0
- fdai_deployment_cli/standalone_management_egress.py +83 -0
- fdai_deployment_cli/standalone_migration_evidence.py +38 -0
- fdai_deployment_cli/standalone_operational_evidence.py +356 -0
- fdai_deployment_cli/standalone_planned_outputs.py +147 -0
- fdai_deployment_cli/standalone_private_access_probe.py +100 -0
- fdai_deployment_cli/standalone_product_profile.py +110 -0
- fdai_deployment_cli/standalone_remote_prepare.py +442 -0
- fdai_deployment_cli/standalone_residual_apply.py +540 -0
- fdai_deployment_cli/standalone_residual_successor.py +431 -0
- fdai_deployment_cli/standalone_review.py +266 -0
- fdai_deployment_cli/standalone_service_update_finalization.py +116 -0
- fdai_deployment_cli/standalone_service_update_recovery.py +277 -0
- fdai_deployment_cli/standalone_stage_targets.py +325 -0
- fdai_deployment_cli/standalone_status.py +67 -0
- fdai_deployment_cli/standalone_terraform_environment.py +237 -0
- fdai_deployment_cli/standalone_transfer_cleanup.py +237 -0
- fdai_deployment_cli/standalone_trial_activation.py +193 -0
- fdai_deployment_cli/state.py +434 -0
- fdai_deployment_cli/state_handoff.py +253 -0
- fdai_deployment_cli/status_projection.py +97 -0
- fdai_deployment_cli/support_install.py +257 -0
- fdai_deployment_cli/target.py +46 -0
- fdai_deployment_cli/trust/capabilities.json +62 -0
- fdai_deployment_cli/trust/deployment-bundle-root.pub +3 -0
- fdai_deployment_cli/trust/deployment-release-root.pub +3 -0
- fdai_deployment_cli/trust/upstream-signing-key.pub +3 -0
- fdai_deployment_cli/trust_roots.py +50 -0
- fdai_deployment_cli-0.1.2.dist-info/METADATA +112 -0
- fdai_deployment_cli-0.1.2.dist-info/RECORD +203 -0
- fdai_deployment_cli-0.1.2.dist-info/WHEEL +4 -0
- fdai_deployment_cli-0.1.2.dist-info/entry_points.txt +2 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"""Prepare signed offline inputs without executing a deployment or granting trust."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
import os
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from tempfile import TemporaryDirectory
|
|
9
|
+
|
|
10
|
+
from fdai_deployment_cli.bundle import extract_bundle_archive, verify_bundle
|
|
11
|
+
from fdai_deployment_cli.compiler import compile_manifest
|
|
12
|
+
from fdai_deployment_cli.contracts import ProvisionProfile, canonical_digest
|
|
13
|
+
from fdai_deployment_cli.offline_kit import (
|
|
14
|
+
materialize_verified_artifacts,
|
|
15
|
+
verify_offline_kit,
|
|
16
|
+
)
|
|
17
|
+
from fdai_deployment_cli.private_output import _open_private_parent, write_private_output
|
|
18
|
+
from fdai_deployment_cli.runtime_release import load_runtime_release, validate_runtime_images
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def prepare_offline_release(
|
|
22
|
+
kit: Path,
|
|
23
|
+
*,
|
|
24
|
+
work_dir: Path,
|
|
25
|
+
profile: ProvisionProfile,
|
|
26
|
+
source_commit: str,
|
|
27
|
+
release_root_pem: bytes,
|
|
28
|
+
bundle_public_key_pem: bytes,
|
|
29
|
+
cli_version: str,
|
|
30
|
+
platform_tag: str,
|
|
31
|
+
) -> dict[str, object]:
|
|
32
|
+
"""Publish a verified snapshot in an existing, private, empty work directory.
|
|
33
|
+
|
|
34
|
+
The caller supplies independently obtained verification keys, not keys trusted
|
|
35
|
+
because they arrived in the kit. Complete v2 runtime inventory and OCI content
|
|
36
|
+
are required, including the ClamAV sidecar. Preparation proves artifact integrity
|
|
37
|
+
only: it neither establishes production release eligibility nor verifies Azure
|
|
38
|
+
permissions, cost, foundation state, Console access, or resource discovery.
|
|
39
|
+
"""
|
|
40
|
+
if profile.connectivity != "offline":
|
|
41
|
+
raise ValueError("offline preparation requires an offline profile")
|
|
42
|
+
if profile.monthly_cost_ceiling <= 0:
|
|
43
|
+
raise ValueError("offline preparation requires an explicit positive monthly cost ceiling")
|
|
44
|
+
directory = _open_private_parent(work_dir / "preparation.json")
|
|
45
|
+
os.close(directory)
|
|
46
|
+
manifest = compile_manifest(profile, source_commit=source_commit)
|
|
47
|
+
verification = verify_offline_kit(
|
|
48
|
+
kit,
|
|
49
|
+
release_root_pem=release_root_pem,
|
|
50
|
+
cli_version=cli_version,
|
|
51
|
+
platform_tag=platform_tag,
|
|
52
|
+
)
|
|
53
|
+
if "runtime/release.json" not in dict(verification.file_digests):
|
|
54
|
+
raise ValueError("toolchain-only kit: a signed runtime release inventory is required")
|
|
55
|
+
destination = work_dir / "prepared"
|
|
56
|
+
if destination.exists() or destination.is_symlink():
|
|
57
|
+
raise ValueError("offline preparation destination already exists")
|
|
58
|
+
with TemporaryDirectory(prefix=".prepare-", dir=work_dir) as temporary:
|
|
59
|
+
staging = Path(temporary)
|
|
60
|
+
artifacts = materialize_verified_artifacts(
|
|
61
|
+
kit, verification, staging / "artifacts", include_all=True
|
|
62
|
+
)
|
|
63
|
+
runtime = load_runtime_release(
|
|
64
|
+
staging / "artifacts",
|
|
65
|
+
expected_source_commit=source_commit,
|
|
66
|
+
expected_platform_tag=platform_tag,
|
|
67
|
+
)
|
|
68
|
+
if runtime.deployment_bundle_sha256 != dict(verification.file_digests).get(
|
|
69
|
+
verification.deployment_bundle
|
|
70
|
+
):
|
|
71
|
+
raise ValueError("runtime inventory does not match the signed deployment bundle")
|
|
72
|
+
image_digests = validate_runtime_images(staging / "artifacts", runtime)
|
|
73
|
+
bundle_root = extract_bundle_archive(artifacts.deployment_bundle, staging / "bundle")
|
|
74
|
+
bundle = verify_bundle(
|
|
75
|
+
bundle_root, public_key_pem=bundle_public_key_pem, cli_version=cli_version
|
|
76
|
+
)
|
|
77
|
+
if bundle.bundle_version != verification.bundle_version:
|
|
78
|
+
raise ValueError("offline kit and deployment bundle versions do not match")
|
|
79
|
+
if not (bundle_root / "infra").is_dir():
|
|
80
|
+
raise ValueError("verified deployment bundle does not contain infra")
|
|
81
|
+
binding = {
|
|
82
|
+
"source_commit": source_commit,
|
|
83
|
+
"profile_digest": canonical_digest(profile.to_mapping()),
|
|
84
|
+
"target_binding": profile.target_binding,
|
|
85
|
+
"monthly_cost_ceiling": profile.monthly_cost_ceiling,
|
|
86
|
+
"offline_manifest_digest": verification.manifest_digest,
|
|
87
|
+
"runtime_release_digest": runtime.digest,
|
|
88
|
+
"deployment_bundle_digest": bundle.manifest_digest,
|
|
89
|
+
"genesis_manifest_digest": manifest.digest,
|
|
90
|
+
"image_content_digests": image_digests,
|
|
91
|
+
}
|
|
92
|
+
if verification.rule_activation_profile is not None:
|
|
93
|
+
binding["rule_activation_profile"] = verification.rule_activation_profile
|
|
94
|
+
binding["rule_activation_profile_digest"] = dict(verification.file_digests)[
|
|
95
|
+
verification.rule_activation_profile
|
|
96
|
+
]
|
|
97
|
+
binding["rule_activation_package_digest"] = verification.manifest_digest
|
|
98
|
+
binding["rule_activation_runtime_environment"] = {
|
|
99
|
+
"FDAI_PROFILE_ID": verification.rule_activation_profile_id,
|
|
100
|
+
"FDAI_RULE_ACTIVATION_SOURCE": "offline_package",
|
|
101
|
+
"FDAI_RULE_ACTIVATION_SOURCE_REF": (f"offline-kit:{verification.manifest_digest}"),
|
|
102
|
+
"FDAI_RULE_ACTIVATION_PACKAGE_DIGEST": verification.manifest_digest,
|
|
103
|
+
"FDAI_RULE_ACTIVATION_SOURCE_RECORDED_AT": (
|
|
104
|
+
verification.rule_activation_profile_created_at
|
|
105
|
+
),
|
|
106
|
+
}
|
|
107
|
+
result: dict[str, object] = {
|
|
108
|
+
"schema_version": "fdai.offline-preparation.v2",
|
|
109
|
+
"state": "prepared",
|
|
110
|
+
"subscription_ready": False,
|
|
111
|
+
"mutation_performed": False,
|
|
112
|
+
"production_release_eligibility": "unverified",
|
|
113
|
+
"binding": binding,
|
|
114
|
+
"preparation_digest": canonical_digest(binding),
|
|
115
|
+
"stage_order": [entry.entry_id for entry in manifest.entries],
|
|
116
|
+
"next_action": "review-foundation-plan",
|
|
117
|
+
"required_checkpoints": [
|
|
118
|
+
"production-release-eligibility",
|
|
119
|
+
"foundation-plan-and-approval",
|
|
120
|
+
"private-execution-host-and-state-handoff",
|
|
121
|
+
"application-plan-and-approval",
|
|
122
|
+
"database-and-semantic-readback",
|
|
123
|
+
"model-readback",
|
|
124
|
+
"authenticated-console-readback",
|
|
125
|
+
"initial-inventory-readback",
|
|
126
|
+
"system-verification",
|
|
127
|
+
"second-run-no-change",
|
|
128
|
+
],
|
|
129
|
+
}
|
|
130
|
+
write_private_output(
|
|
131
|
+
staging / "preparation.json",
|
|
132
|
+
json.dumps(result, sort_keys=True, separators=(",", ":")) + "\n",
|
|
133
|
+
)
|
|
134
|
+
staging.rename(destination)
|
|
135
|
+
return result
|