diff --git a/apis/modelcaches/definition.yaml b/apis/modelcaches/definition.yaml index c53459cf9..3ed1e9071 100644 --- a/apis/modelcaches/definition.yaml +++ b/apis/modelcaches/definition.yaml @@ -86,7 +86,8 @@ spec: properties: matchLabels: type: object - x-kubernetes-preserve-unknown-fields: true + additionalProperties: + type: string status: type: object properties: diff --git a/apis/modeldeployments/definition.yaml b/apis/modeldeployments/definition.yaml index 382785c8f..2457ae486 100644 --- a/apis/modeldeployments/definition.yaml +++ b/apis/modeldeployments/definition.yaml @@ -42,7 +42,8 @@ spec: properties: matchLabels: type: object - x-kubernetes-preserve-unknown-fields: true + additionalProperties: + type: string nodeSelector: type: object description: >- diff --git a/apis/modelservices/definition.yaml b/apis/modelservices/definition.yaml index c7df647ee..b7fbe55f3 100644 --- a/apis/modelservices/definition.yaml +++ b/apis/modelservices/definition.yaml @@ -44,7 +44,8 @@ spec: properties: matchLabels: type: object - x-kubernetes-preserve-unknown-fields: true + additionalProperties: + type: string status: type: object properties: diff --git a/crossplane-project.yaml b/crossplane-project.yaml index ef43f2179..1bad73a87 100644 --- a/crossplane-project.yaml +++ b/crossplane-project.yaml @@ -8,6 +8,11 @@ spec: license: Apache-2.0 description: An open-source AI inference platform built on Crossplane. architectures: [amd64, arm64] + # compose-model-deployment and compose-model-cache match all resources of a + # kind with a bare ResourceSelector, which Crossplane only honours from + # v2.2.1 (https://github.com/crossplane/crossplane/pull/7241). + crossplane: + version: '>=v2.2.1' schemas: languages: [python] functions: @@ -59,7 +64,7 @@ spec: - type: crd git: repository: https://github.com/crossplane/crossplane - ref: release-2.2 + ref: v2.3.2 path: cluster/crds - type: xpkg xpkg: diff --git a/examples/platform/inference-cluster-eks.yaml b/examples/platform/inference-cluster-eks.yaml index d54dc6431..9e6a6fdbc 100644 --- a/examples/platform/inference-cluster-eks.yaml +++ b/examples/platform/inference-cluster-eks.yaml @@ -16,9 +16,6 @@ # EFS CSI StorageClass on the cluster, then set cache.storageClassName # to its name (default 'modelplane-rwx-efs'). # -# The modelplane.ai/cluster label is required for the ModelDeployment -# scheduler to discover this cluster. -# # Delete this InferenceCluster with foreground cascading deletion for a # clean teardown: # @@ -36,7 +33,6 @@ kind: InferenceCluster metadata: name: eks-us-west labels: - modelplane.ai/cluster: "true" modelplane.ai/region: us-west spec: cluster: diff --git a/examples/platform/inference-cluster-existing.yaml b/examples/platform/inference-cluster-existing.yaml index fe5cc30c8..fadf74227 100644 --- a/examples/platform/inference-cluster-existing.yaml +++ b/examples/platform/inference-cluster-existing.yaml @@ -12,7 +12,6 @@ kind: InferenceCluster metadata: name: byo-us-east labels: - modelplane.ai/cluster: "true" modelplane.ai/region: us-east spec: cluster: diff --git a/examples/platform/inference-cluster-gke.yaml b/examples/platform/inference-cluster-gke.yaml index 5e3c40e99..2fb841f2e 100644 --- a/examples/platform/inference-cluster-gke.yaml +++ b/examples/platform/inference-cluster-gke.yaml @@ -10,15 +10,13 @@ # referencing an InferenceClass that describes the hardware shape and # how to provision it - need to be declared. # -# The modelplane.ai/cluster label is required for the ModelDeployment -# scheduler to discover this cluster. Add additional labels to control -# placement via clusterSelector. +# Add labels to this InferenceCluster to control which deployments land on it +# via a ModelDeployment's clusterSelector. apiVersion: modelplane.ai/v1alpha1 kind: InferenceCluster metadata: name: gke-us-central labels: - modelplane.ai/cluster: "true" modelplane.ai/region: us-central spec: cluster: diff --git a/examples/qwen-demo/03-cluster.yaml b/examples/qwen-demo/03-cluster.yaml index 0962f6026..9695eb5c9 100644 --- a/examples/qwen-demo/03-cluster.yaml +++ b/examples/qwen-demo/03-cluster.yaml @@ -11,7 +11,6 @@ kind: InferenceCluster metadata: name: demo-us-central labels: - modelplane.ai/cluster: "true" modelplane.ai/region: us-central spec: cluster: @@ -33,7 +32,6 @@ kind: InferenceCluster metadata: name: demo-us-east labels: - modelplane.ai/cluster: "true" modelplane.ai/region: us-east spec: cluster: @@ -55,7 +53,6 @@ kind: InferenceCluster metadata: name: demo-us-west labels: - modelplane.ai/cluster: "true" modelplane.ai/region: us-west spec: cluster: diff --git a/functions/compose-eks-cluster/pyproject.toml b/functions/compose-eks-cluster/pyproject.toml index a241fd23f..df1fcc12d 100644 --- a/functions/compose-eks-cluster/pyproject.toml +++ b/functions/compose-eks-cluster/pyproject.toml @@ -9,7 +9,7 @@ description = "Compose an EKS cluster with networking, node groups, and IAM role requires-python = ">=3.11,<3.14" license = "Apache-2.0" dependencies = [ - "crossplane-function-sdk-python>=0.13.0", + "crossplane-function-sdk-python>=0.14.0", "click>=8.1.0", "grpcio>=1.73.1", "crossplane-models", diff --git a/functions/compose-gke-cluster/pyproject.toml b/functions/compose-gke-cluster/pyproject.toml index 6c1146d7d..9f0e78f12 100644 --- a/functions/compose-gke-cluster/pyproject.toml +++ b/functions/compose-gke-cluster/pyproject.toml @@ -9,7 +9,7 @@ description = "Compose a GKE cluster with networking, node pools, and service ac requires-python = ">=3.11,<3.14" license = "Apache-2.0" dependencies = [ - "crossplane-function-sdk-python>=0.13.0", + "crossplane-function-sdk-python>=0.14.0", "click>=8.1.0", "grpcio>=1.73.1", "crossplane-models", diff --git a/functions/compose-inference-class/pyproject.toml b/functions/compose-inference-class/pyproject.toml index f06fcbe56..7c3f27f47 100644 --- a/functions/compose-inference-class/pyproject.toml +++ b/functions/compose-inference-class/pyproject.toml @@ -9,7 +9,7 @@ description = "Mark an InferenceClass as ready." requires-python = ">=3.11,<3.14" license = "Apache-2.0" dependencies = [ - "crossplane-function-sdk-python>=0.13.0", + "crossplane-function-sdk-python>=0.14.0", "click>=8.1.0", "grpcio>=1.73.1", "crossplane-models", diff --git a/functions/compose-inference-cluster/pyproject.toml b/functions/compose-inference-cluster/pyproject.toml index 227eb1edb..15b98595c 100644 --- a/functions/compose-inference-cluster/pyproject.toml +++ b/functions/compose-inference-cluster/pyproject.toml @@ -9,7 +9,7 @@ description = "Compose an InferenceCluster from a cluster source and serving sta requires-python = ">=3.11,<3.14" license = "Apache-2.0" dependencies = [ - "crossplane-function-sdk-python>=0.13.0", + "crossplane-function-sdk-python>=0.14.0", "click>=8.1.0", "grpcio>=1.73.1", "crossplane-models", diff --git a/functions/compose-inference-gateway/pyproject.toml b/functions/compose-inference-gateway/pyproject.toml index 6e9aa1879..087392c7b 100644 --- a/functions/compose-inference-gateway/pyproject.toml +++ b/functions/compose-inference-gateway/pyproject.toml @@ -9,7 +9,7 @@ description = "Compose the control plane routing gateway with Envoy Gateway and requires-python = ">=3.11,<3.14" license = "Apache-2.0" dependencies = [ - "crossplane-function-sdk-python>=0.13.0", + "crossplane-function-sdk-python>=0.14.0", "click>=8.1.0", "grpcio>=1.73.1", "crossplane-models", diff --git a/functions/compose-model-cache/function/fn.py b/functions/compose-model-cache/function/fn.py index 74aa970a7..b1f584125 100644 --- a/functions/compose-model-cache/function/fn.py +++ b/functions/compose-model-cache/function/fn.py @@ -44,12 +44,6 @@ # functions set this independently, so they are a contract — change together. REMOTE_NS = "default" -# The cluster-presence label every InferenceCluster carries; the matcher always -# includes it (an empty match_labels is dropped by protobuf). Mirrors -# compose-model-deployment's cluster matching. -LABEL_KEY_CLUSTER = "modelplane.ai/cluster" -LABEL_VALUE_CLUSTER = "true" - # Hydration container. python:3.11-slim has pip; we install huggingface_hub # at runtime. A Modelplane-owned image with the tool preinstalled is a # follow-up (#115). @@ -163,10 +157,11 @@ def resolve_inputs(self) -> bool: Crossplane re-calls the function once it's available. A resolved-but- empty match flows through (match_clusters() -> NoClusters condition). """ - match_labels = {LABEL_KEY_CLUSTER: LABEL_VALUE_CLUSTER} + # require_resources with no match field matches every InferenceCluster; + # narrow only when the user sets a clusterSelector. + match_labels = None if self.xr.spec.clusterSelector and self.xr.spec.clusterSelector.matchLabels: - match_labels.update({k: str(v) for k, v in self.xr.spec.clusterSelector.matchLabels.items()}) - + match_labels = dict(self.xr.spec.clusterSelector.matchLabels) response.require_resources( self.rsp, name="clusters", diff --git a/functions/compose-model-cache/pyproject.toml b/functions/compose-model-cache/pyproject.toml index e5801d906..ede12492b 100644 --- a/functions/compose-model-cache/pyproject.toml +++ b/functions/compose-model-cache/pyproject.toml @@ -9,7 +9,7 @@ description = "Stage a model onto an RWX PVC on every matched InferenceCluster." requires-python = ">=3.11,<3.14" license = "Apache-2.0" dependencies = [ - "crossplane-function-sdk-python>=0.12.0", + "crossplane-function-sdk-python>=0.14.0", "click>=8.1.0", "grpcio>=1.73.1", "crossplane-models", diff --git a/functions/compose-model-cache/tests/test_fn.py b/functions/compose-model-cache/tests/test_fn.py index 5fc957957..f42345d61 100644 --- a/functions/compose-model-cache/tests/test_fn.py +++ b/functions/compose-model-cache/tests/test_fn.py @@ -52,7 +52,7 @@ def _cluster_dict(name: str, pc: str, *, source: str = "GKE") -> dict: return { "apiVersion": "modelplane.ai/v1alpha1", "kind": "InferenceCluster", - "metadata": {"name": name, "labels": {"modelplane.ai/cluster": "true"}}, + "metadata": {"name": name}, "spec": {"cluster": {"source": source, **blocks[source]}}, "status": {"providerConfigRef": {"name": pc}}, } @@ -110,13 +110,12 @@ def _req( return req -# The function always requires every InferenceCluster carrying the cluster -# label, so every response echoes this selector under requirements. +# The function requires every InferenceCluster with a bare selector, so every +# response echoes this selector under requirements. _CLUSTERS_SELECTOR = fnv1.ResourceSelector( api_version="modelplane.ai/v1alpha1", kind="InferenceCluster", ) -_CLUSTERS_SELECTOR.match_labels.labels.update({"modelplane.ai/cluster": "true"}) # The hydration shell script the Job runs (no revision, no auth secret). _HYDRATE_CMD = ( diff --git a/functions/compose-model-deployment/function/fn.py b/functions/compose-model-deployment/function/fn.py index 975cbc81c..c4aa6d583 100644 --- a/functions/compose-model-deployment/function/fn.py +++ b/functions/compose-model-deployment/function/fn.py @@ -31,16 +31,14 @@ CONDITION_REASON_ALL_REPLICAS_READY = "AllReplicasReady" CONDITION_REASON_MODEL_STARTING = "ModelStarting" -# Label keys and values. These are coordination contracts: compose-model-replica -# and compose-model-service read labels that this function writes. +# Label keys stamped on the ModelReplicas and ModelEndpoints this function +# composes, identifying the deployment and cluster they belong to. _LABEL_CLUSTER = "modelplane.ai/cluster" -_LABEL_REPLICA = "modelplane.ai/replica" _LABEL_DEPLOYMENT = "modelplane.ai/deployment" # Per-cluster-local index distinguishing co-located replicas of one deployment. # Read back by the scheduler to reconstruct a replica's (cluster, index) # identity from observed state. Not an ordering - just a collision breaker. _LABEL_INDEX = "modelplane.ai/replica-index" -_LABEL_VALUE_TRUE = "true" # Scheme for gateway-facing URLs. Traffic between the control plane gateway @@ -116,27 +114,26 @@ def compose(self): def resolve_inputs(self): """Declare and fetch required resources. Returns False if critical inputs are missing.""" - # InferenceClusters are matched by the modelplane.ai/cluster=true - # label — a workaround for the empty match_labels protobuf bug. - cluster_match_labels: dict[str, str] = { - _LABEL_CLUSTER: _LABEL_VALUE_TRUE, - } + # Match all InferenceClusters by default — require_resources with no + # match field matches every resource of the kind — narrowing only when + # the user sets a clusterSelector. + clusters_match_labels = None if self.xr.spec.clusterSelector and self.xr.spec.clusterSelector.matchLabels: - cluster_match_labels.update(self.xr.spec.clusterSelector.matchLabels) - + clusters_match_labels = dict(self.xr.spec.clusterSelector.matchLabels) response.require_resources( self.rsp, name="clusters", api_version="modelplane.ai/v1alpha1", kind="InferenceCluster", - match_labels=cluster_match_labels, + match_labels=clusters_match_labels, ) + # Match all ModelReplicas (across all deployments) so the scheduler can + # account for capacity already consumed by other deployments. response.require_resources( self.rsp, name="all-replicas", api_version="modelplane.ai/v1alpha1", kind="ModelReplica", - match_labels={_LABEL_REPLICA: _LABEL_VALUE_TRUE}, ) cluster_dicts = request.get_required_resources(self.req, "clusters") @@ -213,7 +210,6 @@ def compose_replicas(self, matched): name=name.replica(self.xr.metadata.name, cluster_info), namespace=self.xr.metadata.namespace, labels={ - _LABEL_REPLICA: _LABEL_VALUE_TRUE, _LABEL_DEPLOYMENT: self.xr.metadata.name, _LABEL_CLUSTER: cluster_info.name, _LABEL_INDEX: str(cluster_info.index), diff --git a/functions/compose-model-deployment/pyproject.toml b/functions/compose-model-deployment/pyproject.toml index f63e35896..2ea0ec365 100644 --- a/functions/compose-model-deployment/pyproject.toml +++ b/functions/compose-model-deployment/pyproject.toml @@ -9,7 +9,7 @@ description = "Fan out a ModelDeployment to ModelReplicas and ModelEndpoints." requires-python = ">=3.11,<3.14" license = "Apache-2.0" dependencies = [ - "crossplane-function-sdk-python>=0.13.0", + "crossplane-function-sdk-python>=0.14.0", "click>=8.1.0", "grpcio>=1.73.1", "cel-python>=0.3.0", diff --git a/functions/compose-model-deployment/tests/test_fn.py b/functions/compose-model-deployment/tests/test_fn.py index a48b3c428..0b12d4b8c 100644 --- a/functions/compose-model-deployment/tests/test_fn.py +++ b/functions/compose-model-deployment/tests/test_fn.py @@ -112,7 +112,6 @@ def _cluster(name: str, *, ready: bool = True, address: str | None = "10.0.0.1", name="my-model-5ab63", namespace="ml-team", labels={ - "modelplane.ai/replica": "true", "modelplane.ai/deployment": "my-model", "modelplane.ai/cluster": "cluster-a", "modelplane.ai/replica-index": "0", @@ -141,11 +140,10 @@ def _cluster(name: str, *, ready: bool = True, address: str | None = "10.0.0.1", ), ).model_dump(exclude_none=True, mode="json") -# The requirements selectors every want echoes back. +# The requirements selectors every want echoes back. Both are bare selectors +# matching all resources of the kind. _CLUSTER_SEL = fnv1.ResourceSelector(api_version="modelplane.ai/v1alpha1", kind="InferenceCluster") -_CLUSTER_SEL.match_labels.labels.update({"modelplane.ai/cluster": "true"}) _REPLICA_SEL = fnv1.ResourceSelector(api_version="modelplane.ai/v1alpha1", kind="ModelReplica") -_REPLICA_SEL.match_labels.labels.update({"modelplane.ai/replica": "true"}) def _req(xr: dict, *, clusters: list[dict], replicas: list[dict] | None = None, observed: dict | None = None): @@ -282,7 +280,6 @@ async def test_compose(self) -> None: "name": "my-model-5ab63", "namespace": "ml-team", "labels": { - "modelplane.ai/replica": "true", "modelplane.ai/deployment": "my-model", "modelplane.ai/cluster": "cluster-a", "modelplane.ai/replica-index": "0", @@ -421,7 +418,6 @@ async def test_compose(self) -> None: "name": "my-model-5ab63", "namespace": "ml-team", "labels": { - "modelplane.ai/replica": "true", "modelplane.ai/deployment": "my-model", "modelplane.ai/cluster": "cluster-a", "modelplane.ai/replica-index": "0", @@ -452,7 +448,6 @@ async def test_compose(self) -> None: "name": "my-model-5ab63", "namespace": "ml-team", "labels": { - "modelplane.ai/replica": "true", "modelplane.ai/deployment": "my-model", "modelplane.ai/cluster": "cluster-a", "modelplane.ai/replica-index": "0", @@ -547,7 +542,6 @@ async def test_compose(self) -> None: "name": "my-model-5ab63", "namespace": "ml-team", "labels": { - "modelplane.ai/replica": "true", "modelplane.ai/deployment": "my-model", "modelplane.ai/cluster": "cluster-a", "modelplane.ai/replica-index": "0", @@ -621,7 +615,6 @@ async def test_compose(self) -> None: "name": "my-model-f0b76", "namespace": "ml-team", "labels": { - "modelplane.ai/replica": "true", "modelplane.ai/deployment": "my-model", "modelplane.ai/cluster": "cluster-b", "modelplane.ai/replica-index": "0", @@ -716,7 +709,6 @@ async def test_compose(self) -> None: "name": "my-model-5ab63", "namespace": "ml-team", "labels": { - "modelplane.ai/replica": "true", "modelplane.ai/deployment": "my-model", "modelplane.ai/cluster": "cluster-a", "modelplane.ai/replica-index": "0", @@ -812,7 +804,6 @@ async def test_compose(self) -> None: "name": "my-model-5ab63", "namespace": "ml-team", "labels": { - "modelplane.ai/replica": "true", "modelplane.ai/deployment": "my-model", "modelplane.ai/cluster": "cluster-a", "modelplane.ai/replica-index": "0", @@ -849,7 +840,6 @@ async def test_compose(self) -> None: "name": "my-model-609c5", "namespace": "ml-team", "labels": { - "modelplane.ai/replica": "true", "modelplane.ai/deployment": "my-model", "modelplane.ai/cluster": "cluster-a", "modelplane.ai/replica-index": "1", diff --git a/functions/compose-model-deployment/tests/test_scheduling.py b/functions/compose-model-deployment/tests/test_scheduling.py index 5034bdc31..4e782dd90 100644 --- a/functions/compose-model-deployment/tests/test_scheduling.py +++ b/functions/compose-model-deployment/tests/test_scheduling.py @@ -183,7 +183,6 @@ def _replica( name=f"{deployment_name}-{cluster_name}-{index}", namespace="ml-team", labels={ - "modelplane.ai/replica": "true", "modelplane.ai/deployment": deployment_name, "modelplane.ai/cluster": cluster_name, "modelplane.ai/replica-index": str(index), diff --git a/functions/compose-model-endpoint/pyproject.toml b/functions/compose-model-endpoint/pyproject.toml index b5f954850..9495319e6 100644 --- a/functions/compose-model-endpoint/pyproject.toml +++ b/functions/compose-model-endpoint/pyproject.toml @@ -9,7 +9,7 @@ description = "Compose an Envoy Gateway Backend from a ModelEndpoint." requires-python = ">=3.11,<3.14" license = "Apache-2.0" dependencies = [ - "crossplane-function-sdk-python>=0.13.0", + "crossplane-function-sdk-python>=0.14.0", "click>=8.1.0", "grpcio>=1.73.1", "crossplane-models", diff --git a/functions/compose-model-replica/pyproject.toml b/functions/compose-model-replica/pyproject.toml index b776af114..8e76080e5 100644 --- a/functions/compose-model-replica/pyproject.toml +++ b/functions/compose-model-replica/pyproject.toml @@ -9,7 +9,7 @@ description = "Deploy a model on a single InferenceCluster." requires-python = ">=3.11,<3.14" license = "Apache-2.0" dependencies = [ - "crossplane-function-sdk-python>=0.13.0", + "crossplane-function-sdk-python>=0.14.0", "click>=8.1.0", "grpcio>=1.73.1", "crossplane-models", diff --git a/functions/compose-model-service/pyproject.toml b/functions/compose-model-service/pyproject.toml index 233348d82..eb962e415 100644 --- a/functions/compose-model-service/pyproject.toml +++ b/functions/compose-model-service/pyproject.toml @@ -9,7 +9,7 @@ description = "Compose a Gateway API HTTPRoute from a ModelService." requires-python = ">=3.11,<3.14" license = "Apache-2.0" dependencies = [ - "crossplane-function-sdk-python>=0.13.0", + "crossplane-function-sdk-python>=0.14.0", "click>=8.1.0", "grpcio>=1.73.1", "crossplane-models", diff --git a/functions/compose-serving-stack/pyproject.toml b/functions/compose-serving-stack/pyproject.toml index 45a43f531..a0b553e80 100644 --- a/functions/compose-serving-stack/pyproject.toml +++ b/functions/compose-serving-stack/pyproject.toml @@ -9,7 +9,7 @@ description = "Install the serving stack and supporting components on a remote c requires-python = ">=3.11,<3.14" license = "Apache-2.0" dependencies = [ - "crossplane-function-sdk-python>=0.13.0", + "crossplane-function-sdk-python>=0.14.0", "click>=8.1.0", "grpcio>=1.73.1", "crossplane-models", diff --git a/pyproject.toml b/pyproject.toml index db599a2db..ee7453d44 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,7 @@ members = ["functions/*", "schemas/python"] [dependency-groups] dev = [ - "crossplane-function-sdk-python>=0.13.0", + "crossplane-function-sdk-python>=0.14.0", ] [tool.ruff] diff --git a/schemas/.lock.json b/schemas/.lock.json index 1ddc95812..73b58f6e7 100644 --- a/schemas/.lock.json +++ b/schemas/.lock.json @@ -1 +1 @@ -{"packages":{"fs://apis":"319f7f96ce94d2299fc4538b432e579553e27290ceaaff8e226f1e51c8624665","git://https://github.com/crossplane/crossplane/cluster/crds":"32300d8ac6b01bb66702187eea8dee208511c75b","xpkg://xpkg.upbound.io/upbound/provider-aws-ec2:v2.5.0":"sha256:956e2688224c7b42fca94864991478b4ecfec9c9cf52f1cdc42300c1110cece8","xpkg://xpkg.upbound.io/upbound/provider-aws-eks:v2.5.0":"sha256:c51761a15be10295b2c95581448b180889653c20296ebac646624a04f3bf634e","xpkg://xpkg.upbound.io/upbound/provider-aws-iam:v2.5.0":"sha256:854fa2fe081872032cd528d29be58c47e7468744eba7da24b1214aa09610f836","xpkg://xpkg.upbound.io/upbound/provider-gcp-cloudplatform:v2.5.0":"sha256:c84812c0e07576ae1c14103a6f1e69cd1a77b341c5b7939e29c269dd8dc30e03","xpkg://xpkg.upbound.io/upbound/provider-gcp-compute:v2.5.0":"sha256:324c89628bad85f27202dd4322caf969e7d354c9d9895695984301533c939799","xpkg://xpkg.upbound.io/upbound/provider-gcp-container:v2.5.0":"sha256:6e3bb9a041cc1c06b2940904b9c865fe0ea0dd7229e7017dd768e7a55eb18669","xpkg://xpkg.upbound.io/upbound/provider-helm:v1.2.3":"sha256:d81cbe87c15c8555c8388bbb372387084ce8fefdf9a08d0a540a6b4d228a0049","xpkg://xpkg.upbound.io/upbound/provider-helm:v1.2.4":"sha256:e5896e93156845d4f3005abbffa5f1d9468b79944be54203c675f8b61ea54e19","xpkg://xpkg.upbound.io/upbound/provider-kubernetes:v1.2.4":"sha256:b32140022ee86530424da210ed8544f561592a350dc3467365719ffde8c124e1","xpkg://xpkg.upbound.io/upbound/provider-kubernetes:v1.2.5":"sha256:8c9788629608066abc5ba8ae7039214aeaa89619d810a0bfc337102c4f4a897d"}} \ No newline at end of file +{"packages":{"fs://apis":"8084d3526a478e60bf6f8b02eafb0f043198211008b15a5e6ffbbdb3083c9f30","git://https://github.com/crossplane/crossplane/cluster/crds":"90d8b72ad8b829f0bcd7d7d5a98eaa0d579f244a","xpkg://xpkg.upbound.io/upbound/provider-aws-ec2:v2.5.0":"sha256:956e2688224c7b42fca94864991478b4ecfec9c9cf52f1cdc42300c1110cece8","xpkg://xpkg.upbound.io/upbound/provider-aws-eks:v2.5.0":"sha256:c51761a15be10295b2c95581448b180889653c20296ebac646624a04f3bf634e","xpkg://xpkg.upbound.io/upbound/provider-aws-iam:v2.5.0":"sha256:854fa2fe081872032cd528d29be58c47e7468744eba7da24b1214aa09610f836","xpkg://xpkg.upbound.io/upbound/provider-gcp-cloudplatform:v2.5.0":"sha256:c84812c0e07576ae1c14103a6f1e69cd1a77b341c5b7939e29c269dd8dc30e03","xpkg://xpkg.upbound.io/upbound/provider-gcp-compute:v2.5.0":"sha256:324c89628bad85f27202dd4322caf969e7d354c9d9895695984301533c939799","xpkg://xpkg.upbound.io/upbound/provider-gcp-container:v2.5.0":"sha256:6e3bb9a041cc1c06b2940904b9c865fe0ea0dd7229e7017dd768e7a55eb18669","xpkg://xpkg.upbound.io/upbound/provider-helm:v1.2.3":"sha256:d81cbe87c15c8555c8388bbb372387084ce8fefdf9a08d0a540a6b4d228a0049","xpkg://xpkg.upbound.io/upbound/provider-helm:v1.2.4":"sha256:e5896e93156845d4f3005abbffa5f1d9468b79944be54203c675f8b61ea54e19","xpkg://xpkg.upbound.io/upbound/provider-helm:v1.2.5":"sha256:00756c2ac9af9d5addf32bc5ce61c7e99c222ff6286d284a419ee9fa48317f17","xpkg://xpkg.upbound.io/upbound/provider-kubernetes:v1.2.4":"sha256:b32140022ee86530424da210ed8544f561592a350dc3467365719ffde8c124e1","xpkg://xpkg.upbound.io/upbound/provider-kubernetes:v1.2.5":"sha256:8c9788629608066abc5ba8ae7039214aeaa89619d810a0bfc337102c4f4a897d"}} \ No newline at end of file diff --git a/schemas/python/models/ai/modelplane/modelcache/v1alpha1.py b/schemas/python/models/ai/modelplane/modelcache/v1alpha1.py index 53e8f6b63..017e51d01 100644 --- a/schemas/python/models/ai/modelplane/modelcache/v1alpha1.py +++ b/schemas/python/models/ai/modelplane/modelcache/v1alpha1.py @@ -3,7 +3,7 @@ from __future__ import annotations -from typing import Any, Literal +from typing import Literal from pydantic import AwareDatetime, BaseModel, conint, constr @@ -11,7 +11,7 @@ class ClusterSelector(BaseModel): - matchLabels: dict[str, Any] | None = None + matchLabels: dict[str, str] | None = None class CompositionRef(BaseModel): diff --git a/schemas/python/models/ai/modelplane/modeldeployment/v1alpha1.py b/schemas/python/models/ai/modelplane/modeldeployment/v1alpha1.py index ef1747833..08d5b2fe4 100644 --- a/schemas/python/models/ai/modelplane/modeldeployment/v1alpha1.py +++ b/schemas/python/models/ai/modelplane/modeldeployment/v1alpha1.py @@ -3,7 +3,7 @@ from __future__ import annotations -from typing import Any, Literal +from typing import Literal from pydantic import AwareDatetime, BaseModel, Field, conint, constr @@ -11,7 +11,7 @@ class ClusterSelector(BaseModel): - matchLabels: dict[str, Any] | None = None + matchLabels: dict[str, str] | None = None class CompositionRef(BaseModel): diff --git a/schemas/python/models/ai/modelplane/modelservice/v1alpha1.py b/schemas/python/models/ai/modelplane/modelservice/v1alpha1.py index d53ef646a..8a0d1ad8a 100644 --- a/schemas/python/models/ai/modelplane/modelservice/v1alpha1.py +++ b/schemas/python/models/ai/modelplane/modelservice/v1alpha1.py @@ -3,7 +3,7 @@ from __future__ import annotations -from typing import Any, Literal +from typing import Literal from pydantic import AwareDatetime, BaseModel, Field @@ -42,7 +42,7 @@ class Crossplane(BaseModel): class Selector(BaseModel): - matchLabels: dict[str, Any] + matchLabels: dict[str, str] class Endpoint(BaseModel): diff --git a/uv.lock b/uv.lock index 74624d0d8..f7ea5d016 100644 --- a/uv.lock +++ b/uv.lock @@ -83,7 +83,7 @@ dependencies = [ [package.metadata] requires-dist = [ { name = "click", specifier = ">=8.1.0" }, - { name = "crossplane-function-sdk-python", specifier = ">=0.13.0" }, + { name = "crossplane-function-sdk-python", specifier = ">=0.14.0" }, { name = "crossplane-models", editable = "schemas/python" }, { name = "grpcio", specifier = ">=1.73.1" }, ] @@ -102,7 +102,7 @@ dependencies = [ [package.metadata] requires-dist = [ { name = "click", specifier = ">=8.1.0" }, - { name = "crossplane-function-sdk-python", specifier = ">=0.13.0" }, + { name = "crossplane-function-sdk-python", specifier = ">=0.14.0" }, { name = "crossplane-models", editable = "schemas/python" }, { name = "grpcio", specifier = ">=1.73.1" }, ] @@ -121,7 +121,7 @@ dependencies = [ [package.metadata] requires-dist = [ { name = "click", specifier = ">=8.1.0" }, - { name = "crossplane-function-sdk-python", specifier = ">=0.13.0" }, + { name = "crossplane-function-sdk-python", specifier = ">=0.14.0" }, { name = "crossplane-models", editable = "schemas/python" }, { name = "grpcio", specifier = ">=1.73.1" }, ] @@ -140,7 +140,7 @@ dependencies = [ [package.metadata] requires-dist = [ { name = "click", specifier = ">=8.1.0" }, - { name = "crossplane-function-sdk-python", specifier = ">=0.13.0" }, + { name = "crossplane-function-sdk-python", specifier = ">=0.14.0" }, { name = "crossplane-models", editable = "schemas/python" }, { name = "grpcio", specifier = ">=1.73.1" }, ] @@ -160,7 +160,7 @@ dependencies = [ [package.metadata] requires-dist = [ { name = "click", specifier = ">=8.1.0" }, - { name = "crossplane-function-sdk-python", specifier = ">=0.13.0" }, + { name = "crossplane-function-sdk-python", specifier = ">=0.14.0" }, { name = "crossplane-models", editable = "schemas/python" }, { name = "grpcio", specifier = ">=1.73.1" }, { name = "pyyaml", specifier = ">=6.0" }, @@ -180,7 +180,7 @@ dependencies = [ [package.metadata] requires-dist = [ { name = "click", specifier = ">=8.1.0" }, - { name = "crossplane-function-sdk-python", specifier = ">=0.12.0" }, + { name = "crossplane-function-sdk-python", specifier = ">=0.14.0" }, { name = "crossplane-models", editable = "schemas/python" }, { name = "grpcio", specifier = ">=1.73.1" }, ] @@ -201,7 +201,7 @@ dependencies = [ requires-dist = [ { name = "cel-python", specifier = ">=0.3.0" }, { name = "click", specifier = ">=8.1.0" }, - { name = "crossplane-function-sdk-python", specifier = ">=0.13.0" }, + { name = "crossplane-function-sdk-python", specifier = ">=0.14.0" }, { name = "crossplane-models", editable = "schemas/python" }, { name = "grpcio", specifier = ">=1.73.1" }, ] @@ -220,7 +220,7 @@ dependencies = [ [package.metadata] requires-dist = [ { name = "click", specifier = ">=8.1.0" }, - { name = "crossplane-function-sdk-python", specifier = ">=0.13.0" }, + { name = "crossplane-function-sdk-python", specifier = ">=0.14.0" }, { name = "crossplane-models", editable = "schemas/python" }, { name = "grpcio", specifier = ">=1.73.1" }, ] @@ -239,7 +239,7 @@ dependencies = [ [package.metadata] requires-dist = [ { name = "click", specifier = ">=8.1.0" }, - { name = "crossplane-function-sdk-python", specifier = ">=0.13.0" }, + { name = "crossplane-function-sdk-python", specifier = ">=0.14.0" }, { name = "crossplane-models", editable = "schemas/python" }, { name = "grpcio", specifier = ">=1.73.1" }, ] @@ -258,7 +258,7 @@ dependencies = [ [package.metadata] requires-dist = [ { name = "click", specifier = ">=8.1.0" }, - { name = "crossplane-function-sdk-python", specifier = ">=0.13.0" }, + { name = "crossplane-function-sdk-python", specifier = ">=0.14.0" }, { name = "crossplane-models", editable = "schemas/python" }, { name = "grpcio", specifier = ">=1.73.1" }, ] @@ -278,7 +278,7 @@ dependencies = [ [package.metadata] requires-dist = [ { name = "click", specifier = ">=8.1.0" }, - { name = "crossplane-function-sdk-python", specifier = ">=0.13.0" }, + { name = "crossplane-function-sdk-python", specifier = ">=0.14.0" }, { name = "crossplane-models", editable = "schemas/python" }, { name = "grpcio", specifier = ">=1.73.1" }, { name = "pyyaml", specifier = ">=6.0" }, @@ -286,7 +286,7 @@ requires-dist = [ [[package]] name = "crossplane-function-sdk-python" -version = "0.13.0" +version = "0.14.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "grpcio" }, @@ -295,9 +295,9 @@ dependencies = [ { name = "pydantic" }, { name = "structlog" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e6/6d/2e30bba4bc941a15642ec37317e5b45f80d3a701344994d965b8dcd71bd6/crossplane_function_sdk_python-0.13.0.tar.gz", hash = "sha256:815007769ddeb3e2ea4d2b47f5feeb7b15a4692f052d62151e80ce30138eda2b", size = 60018, upload-time = "2026-06-08T20:46:01.76Z" } +sdist = { url = "https://files.pythonhosted.org/packages/78/2c/a5758e9233600b9cb76622f2eeb2dea097629cd82007631c5e9d67ee70e1/crossplane_function_sdk_python-0.14.0.tar.gz", hash = "sha256:bb54f37e743f9a980c1f1b05026e921ebaa293abdd054a045e8e34b926d99607", size = 60076, upload-time = "2026-06-10T23:30:05.259Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/84/9e/4cfc6a3d45f53a5b43a777b7363a0e83f87e96a03e95afc9169512f42cdb/crossplane_function_sdk_python-0.13.0-py3-none-any.whl", hash = "sha256:89ec8d5e5a66bc0ce4551bafe96546329fcc841e3c04706e5ed5e22a37bf4aad", size = 42972, upload-time = "2026-06-08T20:46:00.76Z" }, + { url = "https://files.pythonhosted.org/packages/9c/01/358b0000b7ab412c85e42b192fafbd1d877d5599702fbd808fe2ae9df530/crossplane_function_sdk_python-0.14.0-py3-none-any.whl", hash = "sha256:42323b086c4e8b8fa7d3ce032b5744c29db3cdcdaeb4681997dbf188639e8552", size = 43017, upload-time = "2026-06-10T23:30:04.34Z" }, ] [[package]] @@ -431,7 +431,7 @@ dev = [ [package.metadata] [package.metadata.requires-dev] -dev = [{ name = "crossplane-function-sdk-python", specifier = ">=0.13.0" }] +dev = [{ name = "crossplane-function-sdk-python", specifier = ">=0.14.0" }] [[package]] name = "pendulum"