crossplane-function-pythonic 0.3.0__tar.gz → 0.4.0__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.
- crossplane_function_pythonic-0.3.0/README.md → crossplane_function_pythonic-0.4.0/PKG-INFO +86 -25
- crossplane_function_pythonic-0.3.0/PKG-INFO → crossplane_function_pythonic-0.4.0/README.md +60 -49
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/crossplane/pythonic/__about__.py +1 -1
- crossplane_function_pythonic-0.4.0/crossplane/pythonic/auto_ready.py +194 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/crossplane/pythonic/command.py +12 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/crossplane/pythonic/composite.py +98 -69
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/crossplane/pythonic/function.py +14 -5
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/crossplane/pythonic/protobuf.py +37 -5
- crossplane_function_pythonic-0.4.0/crossplane/pythonic/render.py +630 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/aks-cluster/aks/kubernetescluster.py +1 -1
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/aks-cluster/aks/resourcegroup.py +1 -3
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/aks-cluster/cluster-function-pythonic.yaml +1 -1
- crossplane_function_pythonic-0.4.0/examples/aks-cluster/render.sh +4 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/connection-details-composition/composition.yaml +2 -2
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/connection-details-composition/render.sh +0 -2
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/connections/composition.yaml +1 -1
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/eks-cluster/composition-v2.yaml +11 -11
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/eks-cluster/composition.yaml +11 -11
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/eks-cluster/render-v2.sh +0 -1
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/eks-cluster/render.sh +0 -1
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/filing-system/vcluster.py +3 -3
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/conditions/render.sh +0 -1
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/context/render.sh +0 -1
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/fromYaml/render.sh +0 -1
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/getComposedResource/composition.yaml +2 -2
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/getComposedResource/render.sh +0 -1
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/getCompositeResource/composition.yaml +1 -1
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/getCompositeResource/render.sh +0 -1
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/getCredentialData/render.sh +0 -1
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/getResourceCondition/render.sh +0 -1
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/include/composition.yaml +1 -1
- crossplane_function_pythonic-0.4.0/examples/function-go-templating/functions/include/render.sh +3 -0
- crossplane_function_pythonic-0.4.0/examples/function-go-templating/functions/toYaml/render.sh +3 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/inline/composition.yaml +2 -2
- crossplane_function_pythonic-0.4.0/examples/function-go-templating/inline/render.sh +3 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/recursive/composition-real.yaml +1 -1
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/recursive/composition-wrapper.yaml +1 -1
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/recursive/render.sh +0 -3
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/required-resources/composition.yaml +2 -2
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/required-resources/render.sh +0 -1
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-sequencer/composition.yaml +1 -1
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-sequencer/render.sh +0 -1
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/get-started-app/composition.yaml +2 -2
- crossplane_function_pythonic-0.4.0/examples/get-started-app/observed.yaml +53 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/get-started-app/render.sh +0 -1
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/helm-copy-secret/render.sh +0 -1
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/helm-copy-secret/vcluster.py +3 -3
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/import-existing-vpc/composition.yaml +1 -1
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/import-existing-vpc/render.sh +0 -3
- crossplane_function_pythonic-0.4.0/examples/run-all.sh +3 -0
- crossplane_function_pythonic-0.3.0/examples/helm-copy-secret/run-function.sh → crossplane_function_pythonic-0.4.0/examples/single-purpose/render.sh +1 -1
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/usages-extra/composition.yaml +2 -2
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/usages-extra/render.sh +0 -1
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/pyproject.toml +5 -3
- crossplane_function_pythonic-0.3.0/crossplane/pythonic/auto_ready.py +0 -153
- crossplane_function_pythonic-0.3.0/crossplane/pythonic/render.py +0 -462
- crossplane_function_pythonic-0.3.0/examples/.dev/functions.yaml +0 -13
- crossplane_function_pythonic-0.3.0/examples/aks-cluster/functions.yaml +0 -10
- crossplane_function_pythonic-0.3.0/examples/aks-cluster/render.sh +0 -10
- crossplane_function_pythonic-0.3.0/examples/connection-details-composition/functions.yaml +0 -8
- crossplane_function_pythonic-0.3.0/examples/eks-cluster/functions.yaml +0 -8
- crossplane_function_pythonic-0.3.0/examples/filing-system/function.yaml +0 -10
- crossplane_function_pythonic-0.3.0/examples/function-go-templating/conditions/functions.yaml +0 -10
- crossplane_function_pythonic-0.3.0/examples/function-go-templating/context/functions.yaml +0 -10
- crossplane_function_pythonic-0.3.0/examples/function-go-templating/functions/fromYaml/functions.yaml +0 -9
- crossplane_function_pythonic-0.3.0/examples/function-go-templating/functions/getComposedResource/functions.yaml +0 -9
- crossplane_function_pythonic-0.3.0/examples/function-go-templating/functions/getCompositeResource/functions.yaml +0 -9
- crossplane_function_pythonic-0.3.0/examples/function-go-templating/functions/getCredentialData/functions.yaml +0 -9
- crossplane_function_pythonic-0.3.0/examples/function-go-templating/functions/getResourceCondition/functions.yaml +0 -9
- crossplane_function_pythonic-0.3.0/examples/function-go-templating/functions/include/functions.yaml +0 -9
- crossplane_function_pythonic-0.3.0/examples/function-go-templating/functions/include/render.sh +0 -4
- crossplane_function_pythonic-0.3.0/examples/function-go-templating/functions/toYaml/functions.yaml +0 -9
- crossplane_function_pythonic-0.3.0/examples/function-go-templating/functions/toYaml/render.sh +0 -4
- crossplane_function_pythonic-0.3.0/examples/function-go-templating/inline/functions.yaml +0 -9
- crossplane_function_pythonic-0.3.0/examples/function-go-templating/inline/render.sh +0 -4
- crossplane_function_pythonic-0.3.0/examples/function-go-templating/recursive/functions.yaml +0 -9
- crossplane_function_pythonic-0.3.0/examples/function-go-templating/required-resources/functions.yaml +0 -9
- crossplane_function_pythonic-0.3.0/examples/function-sequencer/functions.yaml +0 -8
- crossplane_function_pythonic-0.3.0/examples/get-started-app/functions.yaml +0 -8
- crossplane_function_pythonic-0.3.0/examples/helm-copy-secret/functions.yaml +0 -8
- crossplane_function_pythonic-0.3.0/examples/import-existing-vpc/functions.yaml +0 -8
- crossplane_function_pythonic-0.3.0/examples/single-purpose/functions.yaml +0 -8
- crossplane_function_pythonic-0.3.0/examples/single-purpose/render.sh +0 -4
- crossplane_function_pythonic-0.3.0/examples/usages-extra/functions.yaml +0 -9
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/.gitignore +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/LICENSE +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/crossplane/pythonic/__init__.py +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/crossplane/pythonic/__main__.py +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/crossplane/pythonic/grpc.py +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/crossplane/pythonic/main.py +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/crossplane/pythonic/packages.py +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/crossplane/pythonic/version.py +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/aks-cluster/README.md +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/aks-cluster/composition.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/aks-cluster/definition.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/aks-cluster/install.sh +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/aks-cluster/kustomization.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/aks-cluster/providers.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/aks-cluster/xr.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/connection-details-composition/access-keys.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/connection-details-composition/definition.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/connection-details-composition/secrets.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/connection-details-composition/user.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/connection-details-composition/xr.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/connections/composite-connection.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/connections/rds-connection.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/connections/rds-observed.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/connections/render.sh +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/connections/step-credential.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/connections/xr.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/eks-cluster/definition.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/eks-cluster/xr.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/filing-system/README.md +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/filing-system/composition.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/filing-system/definition.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/filing-system/kustomization.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/filing-system/runtime.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/filing-system/vcluster.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/conditions/composition.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/conditions/xr.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/conditions/xrd.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/context/composition.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/context/environmentConfigs.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/context/xr.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/context/xrd.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/fromYaml/composition.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/fromYaml/xr.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/getComposedResource/observed.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/getComposedResource/xr.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/getCompositeResource/xr.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/getCredentialData/composition.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/getCredentialData/credentials.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/getCredentialData/xr.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/getResourceCondition/composition.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/getResourceCondition/observed.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/getResourceCondition/xr.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/include/xr.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/toYaml/composition.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/toYaml/xr.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/inline/xr.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/recursive/xr.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/required-resources/required-resources.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/required-resources/xr.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-sequencer/observed.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-sequencer/sequencer.py +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-sequencer/xr.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/get-started-app/definition.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/get-started-app/xr.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/helm-copy-secret/composition.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/helm-copy-secret/kustomization.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/helm-copy-secret/xr.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/helm-copy-secret/xrd.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/import-existing-vpc/README.md +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/import-existing-vpc/definition.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/import-existing-vpc/observed.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/import-existing-vpc/provider-ec2.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/import-existing-vpc/xr.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/single-purpose/xr.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/usages-extra/extraResources.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/usages-extra/observedResources.yaml +0 -0
- {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/usages-extra/xr.yaml +0 -0
|
@@ -1,3 +1,29 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: crossplane-function-pythonic
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: A Python centric Crossplane Function
|
|
5
|
+
Project-URL: Documentation, https://github.com/crossplane-contrib/function-pythonic#readme
|
|
6
|
+
Project-URL: Issues, https://github.com/crossplane-contrib/function-pythonic/issues
|
|
7
|
+
Project-URL: Source, https://github.com/crossplane-contrib/function-pythonic
|
|
8
|
+
Author-email: Patrick J McNerthney <pat@mcnerthney.com>
|
|
9
|
+
License-Expression: Apache-2.0
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Programming Language :: Python
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
16
|
+
Requires-Python: <3.15,>=3.12
|
|
17
|
+
Requires-Dist: crossplane-function-sdk-python==0.11.0
|
|
18
|
+
Requires-Dist: inflect==7.5.0
|
|
19
|
+
Requires-Dist: kr8s==0.20.15
|
|
20
|
+
Requires-Dist: pyyaml==6.0.3
|
|
21
|
+
Provides-Extra: packages
|
|
22
|
+
Requires-Dist: kopf==1.42.5; extra == 'packages'
|
|
23
|
+
Provides-Extra: pip-install
|
|
24
|
+
Requires-Dist: pip==26.0.1; extra == 'pip-install'
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
|
|
1
27
|
# function-pythonic
|
|
2
28
|
|
|
3
29
|
## Introduction
|
|
@@ -30,7 +56,7 @@ spec:
|
|
|
30
56
|
composite: |
|
|
31
57
|
class VpcComposite(BaseComposite):
|
|
32
58
|
def compose(self):
|
|
33
|
-
vpc = self.resources.vpc('ec2.aws.crossplane.io/v1beta1'
|
|
59
|
+
vpc = self.resources.vpc('VPC', 'ec2.aws.crossplane.io/v1beta1')
|
|
34
60
|
vpc.spec.forProvider.region = self.spec.region
|
|
35
61
|
vpc.spec.forProvider.cidrBlock = self.spec.cidr
|
|
36
62
|
self.status.vpcId = vpc.status.atProvider.vpcId
|
|
@@ -57,7 +83,7 @@ kind: Function
|
|
|
57
83
|
metadata:
|
|
58
84
|
name: function-pythonic
|
|
59
85
|
spec:
|
|
60
|
-
package: xpkg.upbound.io/crossplane-contrib/function-pythonic:v0.
|
|
86
|
+
package: xpkg.upbound.io/crossplane-contrib/function-pythonic:v0.4.0
|
|
61
87
|
```
|
|
62
88
|
|
|
63
89
|
### Crossplane V1
|
|
@@ -69,7 +95,7 @@ kind: Function
|
|
|
69
95
|
metadata:
|
|
70
96
|
name: function-pythonic
|
|
71
97
|
spec:
|
|
72
|
-
package: xpkg.upbound.io/crossplane-contrib/function-pythonic:v0.
|
|
98
|
+
package: xpkg.upbound.io/crossplane-contrib/function-pythonic:v0.4.0
|
|
73
99
|
runtimeConfigRef:
|
|
74
100
|
name: function-pythonic
|
|
75
101
|
--
|
|
@@ -104,12 +130,12 @@ condition, the composition will be terminated or the observed value for that fie
|
|
|
104
130
|
be used, depending on the `unknownsFatal` settings.
|
|
105
131
|
|
|
106
132
|
Take the following example:
|
|
107
|
-
```
|
|
108
|
-
vpc = self.resources.VPC('ec2.aws.crossplane.io/v1beta1'
|
|
133
|
+
```python
|
|
134
|
+
vpc = self.resources.VPC('VPC', 'ec2.aws.crossplane.io/v1beta1')
|
|
109
135
|
vpc.spec.forProvider.region = 'us-east-1
|
|
110
136
|
vpc.spec.forProvider.cidrBlock = '10.0.0.0/16'
|
|
111
137
|
|
|
112
|
-
subnet = self.resources.SubnetA('ec2.aws.crossplane.io/v1beta1'
|
|
138
|
+
subnet = self.resources.SubnetA('Subnet', 'ec2.aws.crossplane.io/v1beta1')
|
|
113
139
|
subnet.spec.forProvider.region = 'us-east-1'
|
|
114
140
|
subnet.spec.forProvider.vpcId = vpc.status.atProvider.vpcId
|
|
115
141
|
subnet.spec.forProvider.availabilityZone = 'us-east-1a'
|
|
@@ -126,19 +152,46 @@ overridden for all composed resource by setting the Composite `self.unknownsFata
|
|
|
126
152
|
to False, or at the individual composed resource level by setting the
|
|
127
153
|
`Resource.unknownsFatal` field to False.
|
|
128
154
|
|
|
155
|
+
## Explicit Dependencies
|
|
156
|
+
|
|
157
|
+
At times, the above implicit dependency handling does not account for all cases.
|
|
158
|
+
Explicit dependencies can be configured using the resource `addDependency` method.
|
|
159
|
+
The dependency's "ready" is used to determine when that dependency is available
|
|
160
|
+
for use. The dependency's ready state can either be explictly set, or will be
|
|
161
|
+
defaulted to it's auto-ready calculation.
|
|
162
|
+
|
|
163
|
+
Here is an example of specifying an explicit dependency:
|
|
164
|
+
```yaml
|
|
165
|
+
crd = self.resources.KarpenterCrdRelease('Release', 'helm.crossplane.io/v1beta1')
|
|
166
|
+
crd.spec.deletionPolicy = 'Orphan'
|
|
167
|
+
crd.spec.forProvider.chart.repository = 'oci://public.ecr.aws/karpenter'
|
|
168
|
+
crd.spec.forProvider.chart.name = 'karpenter-crd'
|
|
169
|
+
crd.spec.forProvider.chart.version = '1.8.6'
|
|
170
|
+
crd.spec.forProvider.namespace = 'karpenter'
|
|
171
|
+
crd.externalName = 'karpenter-crd'
|
|
172
|
+
karpenter = self.resources.KarpenterRelease('Release', 'helm.crossplane.io/v1beta1')
|
|
173
|
+
karpenter.addDependency(crd)
|
|
174
|
+
karpenter.spec.deletionPolicy = 'Orphan'
|
|
175
|
+
karpenter.spec.forProvider.chart.repository = 'oci://public.ecr.aws/karpenter'
|
|
176
|
+
karpenter.spec.forProvider.chart.name = 'karpenter'
|
|
177
|
+
karpenter.spec.forProvider.chart.version = '1.8.6'
|
|
178
|
+
karpenter.spec.forProvider.namespace = 'karpenter'
|
|
179
|
+
karpenter.externalName = 'karpenter'
|
|
180
|
+
```
|
|
181
|
+
|
|
129
182
|
## Usage Dependencies
|
|
130
183
|
|
|
131
184
|
function-pythonic can be configured to automatically create
|
|
132
185
|
[Crossplane Usages](https://docs.crossplane.io/latest/managed-resources/usages/)
|
|
133
186
|
dependencies between resources. Modifying the above VPC example with:
|
|
134
|
-
```
|
|
187
|
+
```python
|
|
135
188
|
self.usages = True
|
|
136
189
|
|
|
137
|
-
vpc = self.resources.VPC('ec2.aws.crossplane.io/v1beta1'
|
|
190
|
+
vpc = self.resources.VPC('VPC', 'ec2.aws.crossplane.io/v1beta1')
|
|
138
191
|
vpc.spec.forProvider.region = 'us-east-1
|
|
139
192
|
vpc.spec.forProvider.cidrBlock = '10.0.0.0/16'
|
|
140
193
|
|
|
141
|
-
subnet = self.resources.SubnetA('ec2.aws.crossplane.io/v1beta1'
|
|
194
|
+
subnet = self.resources.SubnetA('Subnet', 'ec2.aws.crossplane.io/v1beta1')
|
|
142
195
|
subnet.spec.forProvider.region = 'us-east-1'
|
|
143
196
|
subnet.spec.forProvider.vpcId = vpc.status.atProvider.vpcId
|
|
144
197
|
subnet.spec.forProvider.availabilityZone = 'us-east-1a'
|
|
@@ -179,7 +232,7 @@ Calling a message or map will clear it and will set any provided key word
|
|
|
179
232
|
arguments. For example, this will either create or clear the resource
|
|
180
233
|
and then set its apiVersion and kind:
|
|
181
234
|
```python
|
|
182
|
-
response.desired.resources.vpc.resource(apiVersion='ec2.aws.crossplane.io/v1beta1'
|
|
235
|
+
response.desired.resources.vpc.resource(kind='VPC', apiVersion='ec2.aws.crossplane.io/v1beta1')
|
|
183
236
|
```
|
|
184
237
|
The following functions are provided to create Protobuf structures:
|
|
185
238
|
| Function | Description |
|
|
@@ -236,8 +289,8 @@ The BaseComposite class provides the following fields for manipulating the Compo
|
|
|
236
289
|
| self.conditions | Conditions | The composite desired and observed conditions, read from observed if not in desired |
|
|
237
290
|
| self.results | Results | Returned results applied to the Composite and optionally on the Claim |
|
|
238
291
|
| self.connectionSecret | Map | The name, namespace, and resourceName to use when generating the connection secret in Crossplane v2 |
|
|
239
|
-
| self.connection | Map | The composite desired connection
|
|
240
|
-
| self.connection.observed | Map | The composite observed connection
|
|
292
|
+
| self.connection | Map | The composite desired connection details |
|
|
293
|
+
| self.connection.observed | Map | The composite observed connection details |
|
|
241
294
|
| self.ready | Boolean | The composite desired ready state |
|
|
242
295
|
|
|
243
296
|
The BaseComposite also provides access to the following Crossplane Function level features:
|
|
@@ -254,9 +307,9 @@ The BaseComposite also provides access to the following Crossplane Function leve
|
|
|
254
307
|
| self.environment | Map | The response environment, initialized from the request context environment |
|
|
255
308
|
| self.requireds | Requireds | Request and read additional local Kubernetes resources |
|
|
256
309
|
| self.resources | Resources | Define and process composed resources |
|
|
257
|
-
| self.unknownsFatal | Boolean | Terminate the composition if already created resources are assigned unknown values, default True |
|
|
258
310
|
| self.usages| Boolean | Generate Crossplane Usages for resource dependencies, default False |
|
|
259
311
|
| self.autoReady | Boolean | Perform auto ready processing on all composed resources, default True |
|
|
312
|
+
| self.unknownsFatal | Boolean | Terminate the composition if already created resources are assigned unknown values, default False |
|
|
260
313
|
|
|
261
314
|
### Composed Resources
|
|
262
315
|
|
|
@@ -281,9 +334,11 @@ Resource class:
|
|
|
281
334
|
| Resource.conditions | Conditions | The resource conditions |
|
|
282
335
|
| Resource.connection | Map | The resource observed connection details |
|
|
283
336
|
| Resource.ready | Boolean | The resource ready state |
|
|
284
|
-
| Resource.
|
|
337
|
+
| Resource.addDependency | Method | Add another composed resource as a dependency |
|
|
338
|
+
| Resource.setReadyCondition | Method | Set Resource.ready to the Ready Condition status |
|
|
285
339
|
| Resource.usages | Boolean | Generate Crossplane Usages for this resource, default is Composite.autoReady |
|
|
286
340
|
| Resource.autoReady | Boolean | Perform auto ready processing on this resource, default is Composite.autoReady |
|
|
341
|
+
| Resource.unknownsFatal | Boolean | Terminate the composition if this resource has been created and is assigned unknown values, default is Composite.unknownsFatal |
|
|
287
342
|
|
|
288
343
|
### Required Resources
|
|
289
344
|
|
|
@@ -382,28 +437,34 @@ $ pip install crossplane-function-pythonic
|
|
|
382
437
|
Then to render function-pythonic Compositions, use the `function-pythonic render ...`
|
|
383
438
|
command.
|
|
384
439
|
```shell
|
|
385
|
-
$ function-pythonic render
|
|
386
|
-
usage: Crossplane Function Pythonic render [-h] [--debug] [--log-name-width WIDTH] [--
|
|
387
|
-
[--allow-oversize-protos] [--
|
|
388
|
-
[--
|
|
389
|
-
[--
|
|
390
|
-
|
|
440
|
+
$ function-pythonic render --help
|
|
441
|
+
usage: Crossplane Function Pythonic render [-h] [--debug] [--log-name-width WIDTH] [--logger-level LOGGER=LEVEL] [--python-path DIRECTORY]
|
|
442
|
+
[--render-unknowns] [--allow-oversize-protos] [--crossplane-v1] [--kube-context CONTEXT]
|
|
443
|
+
[--context-files KEY=PATH] [--context-values KEY=VALUE] [--observed-resources PATH]
|
|
444
|
+
[--required-resources PATH] [--secret-store PATH] [--include-full-xr] [--include-connection-xr]
|
|
445
|
+
[--include-function-results] [--include-context]
|
|
446
|
+
COMPOSITE [COMPOSITION]
|
|
391
447
|
|
|
392
448
|
positional arguments:
|
|
393
|
-
|
|
394
|
-
|
|
449
|
+
COMPOSITE A YAML file containing the Composite resource to render, or kind:apiVersion:namespace:name of cluster Composite.
|
|
450
|
+
COMPOSITION A YAML file containing the Composition resource, or the complete path of a function-pythonic BaseComposite subclass.
|
|
395
451
|
|
|
396
452
|
options:
|
|
397
453
|
-h, --help show this help message and exit
|
|
398
454
|
--debug, -d Emit debug logs.
|
|
399
455
|
--log-name-width WIDTH
|
|
400
456
|
Width of the logger name in the log output, default 40.
|
|
457
|
+
--logger-level LOGGER=LEVEL
|
|
458
|
+
Logger level, for example: botocore.hooks=INFO
|
|
401
459
|
--python-path DIRECTORY
|
|
402
460
|
Filing system directories to add to the python path.
|
|
403
461
|
--render-unknowns, -u
|
|
404
462
|
Render resources with unknowns, useful during local development.
|
|
405
463
|
--allow-oversize-protos
|
|
406
464
|
Allow oversized protobuf messages
|
|
465
|
+
--crossplane-v1 Enable Crossplane V1 compatibility mode
|
|
466
|
+
--kube-context, -k CONTEXT
|
|
467
|
+
The kubectl context to use to obtain external resources from, such as required resources, connections, etc.
|
|
407
468
|
--context-files KEY=PATH
|
|
408
469
|
Context key-value pairs to pass to the Function pipeline. Values must be files containing YAML/JSON.
|
|
409
470
|
--context-values KEY=VALUE
|
|
@@ -419,7 +480,7 @@ options:
|
|
|
419
480
|
--include-connection-xr
|
|
420
481
|
Include the Composite connection values in the rendered output as a resource of kind: Connection.
|
|
421
482
|
--include-function-results, -r
|
|
422
|
-
Include informational and warning messages from Functions in the rendered output as resources of kind: Result
|
|
483
|
+
Include informational and warning messages from Functions in the rendered output as resources of kind: Result.
|
|
423
484
|
--include-context, -c
|
|
424
485
|
Include the context in the rendered output as a resource of kind: Context.
|
|
425
486
|
```
|
|
@@ -555,7 +616,7 @@ kind: Function
|
|
|
555
616
|
metadata:
|
|
556
617
|
name: function-pythonic
|
|
557
618
|
spec:
|
|
558
|
-
package: xpkg.upbound.io/crossplane-contrib/function-pythonic:v0.
|
|
619
|
+
package: xpkg.upbound.io/crossplane-contrib/function-pythonic:v0.4.0
|
|
559
620
|
runtimeConfigRef:
|
|
560
621
|
name: function-pythonic
|
|
561
622
|
---
|
|
@@ -639,7 +700,7 @@ data:
|
|
|
639
700
|
from crossplane.pythonic import BaseComposite
|
|
640
701
|
class GreetingComposite(BaseComposite):
|
|
641
702
|
def compose(self):
|
|
642
|
-
cm = self.resources.ConfigMap('
|
|
703
|
+
cm = self.resources.ConfigMap('ConfigMap', 'v1')
|
|
643
704
|
cm.data.greeting = f"Hello, {self.parameters.who}!"
|
|
644
705
|
```
|
|
645
706
|
```yaml
|
|
@@ -1,27 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: crossplane-function-pythonic
|
|
3
|
-
Version: 0.3.0
|
|
4
|
-
Summary: A Python centric Crossplane Function
|
|
5
|
-
Project-URL: Documentation, https://github.com/crossplane-contrib/function-pythonic#readme
|
|
6
|
-
Project-URL: Issues, https://github.com/crossplane-contrib/function-pythonic/issues
|
|
7
|
-
Project-URL: Source, https://github.com/crossplane-contrib/function-pythonic
|
|
8
|
-
Author-email: Patrick J McNerthney <pat@mcnerthney.com>
|
|
9
|
-
License-Expression: Apache-2.0
|
|
10
|
-
License-File: LICENSE
|
|
11
|
-
Classifier: Development Status :: 4 - Beta
|
|
12
|
-
Classifier: Programming Language :: Python
|
|
13
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.14
|
|
16
|
-
Requires-Python: <3.15,>=3.12
|
|
17
|
-
Requires-Dist: crossplane-function-sdk-python==0.10.0
|
|
18
|
-
Requires-Dist: pyyaml==6.0.3
|
|
19
|
-
Provides-Extra: packages
|
|
20
|
-
Requires-Dist: kopf==1.40.0; extra == 'packages'
|
|
21
|
-
Provides-Extra: pip-install
|
|
22
|
-
Requires-Dist: pip==25.3; extra == 'pip-install'
|
|
23
|
-
Description-Content-Type: text/markdown
|
|
24
|
-
|
|
25
1
|
# function-pythonic
|
|
26
2
|
|
|
27
3
|
## Introduction
|
|
@@ -54,7 +30,7 @@ spec:
|
|
|
54
30
|
composite: |
|
|
55
31
|
class VpcComposite(BaseComposite):
|
|
56
32
|
def compose(self):
|
|
57
|
-
vpc = self.resources.vpc('ec2.aws.crossplane.io/v1beta1'
|
|
33
|
+
vpc = self.resources.vpc('VPC', 'ec2.aws.crossplane.io/v1beta1')
|
|
58
34
|
vpc.spec.forProvider.region = self.spec.region
|
|
59
35
|
vpc.spec.forProvider.cidrBlock = self.spec.cidr
|
|
60
36
|
self.status.vpcId = vpc.status.atProvider.vpcId
|
|
@@ -81,7 +57,7 @@ kind: Function
|
|
|
81
57
|
metadata:
|
|
82
58
|
name: function-pythonic
|
|
83
59
|
spec:
|
|
84
|
-
package: xpkg.upbound.io/crossplane-contrib/function-pythonic:v0.
|
|
60
|
+
package: xpkg.upbound.io/crossplane-contrib/function-pythonic:v0.4.0
|
|
85
61
|
```
|
|
86
62
|
|
|
87
63
|
### Crossplane V1
|
|
@@ -93,7 +69,7 @@ kind: Function
|
|
|
93
69
|
metadata:
|
|
94
70
|
name: function-pythonic
|
|
95
71
|
spec:
|
|
96
|
-
package: xpkg.upbound.io/crossplane-contrib/function-pythonic:v0.
|
|
72
|
+
package: xpkg.upbound.io/crossplane-contrib/function-pythonic:v0.4.0
|
|
97
73
|
runtimeConfigRef:
|
|
98
74
|
name: function-pythonic
|
|
99
75
|
--
|
|
@@ -128,12 +104,12 @@ condition, the composition will be terminated or the observed value for that fie
|
|
|
128
104
|
be used, depending on the `unknownsFatal` settings.
|
|
129
105
|
|
|
130
106
|
Take the following example:
|
|
131
|
-
```
|
|
132
|
-
vpc = self.resources.VPC('ec2.aws.crossplane.io/v1beta1'
|
|
107
|
+
```python
|
|
108
|
+
vpc = self.resources.VPC('VPC', 'ec2.aws.crossplane.io/v1beta1')
|
|
133
109
|
vpc.spec.forProvider.region = 'us-east-1
|
|
134
110
|
vpc.spec.forProvider.cidrBlock = '10.0.0.0/16'
|
|
135
111
|
|
|
136
|
-
subnet = self.resources.SubnetA('ec2.aws.crossplane.io/v1beta1'
|
|
112
|
+
subnet = self.resources.SubnetA('Subnet', 'ec2.aws.crossplane.io/v1beta1')
|
|
137
113
|
subnet.spec.forProvider.region = 'us-east-1'
|
|
138
114
|
subnet.spec.forProvider.vpcId = vpc.status.atProvider.vpcId
|
|
139
115
|
subnet.spec.forProvider.availabilityZone = 'us-east-1a'
|
|
@@ -150,19 +126,46 @@ overridden for all composed resource by setting the Composite `self.unknownsFata
|
|
|
150
126
|
to False, or at the individual composed resource level by setting the
|
|
151
127
|
`Resource.unknownsFatal` field to False.
|
|
152
128
|
|
|
129
|
+
## Explicit Dependencies
|
|
130
|
+
|
|
131
|
+
At times, the above implicit dependency handling does not account for all cases.
|
|
132
|
+
Explicit dependencies can be configured using the resource `addDependency` method.
|
|
133
|
+
The dependency's "ready" is used to determine when that dependency is available
|
|
134
|
+
for use. The dependency's ready state can either be explictly set, or will be
|
|
135
|
+
defaulted to it's auto-ready calculation.
|
|
136
|
+
|
|
137
|
+
Here is an example of specifying an explicit dependency:
|
|
138
|
+
```yaml
|
|
139
|
+
crd = self.resources.KarpenterCrdRelease('Release', 'helm.crossplane.io/v1beta1')
|
|
140
|
+
crd.spec.deletionPolicy = 'Orphan'
|
|
141
|
+
crd.spec.forProvider.chart.repository = 'oci://public.ecr.aws/karpenter'
|
|
142
|
+
crd.spec.forProvider.chart.name = 'karpenter-crd'
|
|
143
|
+
crd.spec.forProvider.chart.version = '1.8.6'
|
|
144
|
+
crd.spec.forProvider.namespace = 'karpenter'
|
|
145
|
+
crd.externalName = 'karpenter-crd'
|
|
146
|
+
karpenter = self.resources.KarpenterRelease('Release', 'helm.crossplane.io/v1beta1')
|
|
147
|
+
karpenter.addDependency(crd)
|
|
148
|
+
karpenter.spec.deletionPolicy = 'Orphan'
|
|
149
|
+
karpenter.spec.forProvider.chart.repository = 'oci://public.ecr.aws/karpenter'
|
|
150
|
+
karpenter.spec.forProvider.chart.name = 'karpenter'
|
|
151
|
+
karpenter.spec.forProvider.chart.version = '1.8.6'
|
|
152
|
+
karpenter.spec.forProvider.namespace = 'karpenter'
|
|
153
|
+
karpenter.externalName = 'karpenter'
|
|
154
|
+
```
|
|
155
|
+
|
|
153
156
|
## Usage Dependencies
|
|
154
157
|
|
|
155
158
|
function-pythonic can be configured to automatically create
|
|
156
159
|
[Crossplane Usages](https://docs.crossplane.io/latest/managed-resources/usages/)
|
|
157
160
|
dependencies between resources. Modifying the above VPC example with:
|
|
158
|
-
```
|
|
161
|
+
```python
|
|
159
162
|
self.usages = True
|
|
160
163
|
|
|
161
|
-
vpc = self.resources.VPC('ec2.aws.crossplane.io/v1beta1'
|
|
164
|
+
vpc = self.resources.VPC('VPC', 'ec2.aws.crossplane.io/v1beta1')
|
|
162
165
|
vpc.spec.forProvider.region = 'us-east-1
|
|
163
166
|
vpc.spec.forProvider.cidrBlock = '10.0.0.0/16'
|
|
164
167
|
|
|
165
|
-
subnet = self.resources.SubnetA('ec2.aws.crossplane.io/v1beta1'
|
|
168
|
+
subnet = self.resources.SubnetA('Subnet', 'ec2.aws.crossplane.io/v1beta1')
|
|
166
169
|
subnet.spec.forProvider.region = 'us-east-1'
|
|
167
170
|
subnet.spec.forProvider.vpcId = vpc.status.atProvider.vpcId
|
|
168
171
|
subnet.spec.forProvider.availabilityZone = 'us-east-1a'
|
|
@@ -203,7 +206,7 @@ Calling a message or map will clear it and will set any provided key word
|
|
|
203
206
|
arguments. For example, this will either create or clear the resource
|
|
204
207
|
and then set its apiVersion and kind:
|
|
205
208
|
```python
|
|
206
|
-
response.desired.resources.vpc.resource(apiVersion='ec2.aws.crossplane.io/v1beta1'
|
|
209
|
+
response.desired.resources.vpc.resource(kind='VPC', apiVersion='ec2.aws.crossplane.io/v1beta1')
|
|
207
210
|
```
|
|
208
211
|
The following functions are provided to create Protobuf structures:
|
|
209
212
|
| Function | Description |
|
|
@@ -260,8 +263,8 @@ The BaseComposite class provides the following fields for manipulating the Compo
|
|
|
260
263
|
| self.conditions | Conditions | The composite desired and observed conditions, read from observed if not in desired |
|
|
261
264
|
| self.results | Results | Returned results applied to the Composite and optionally on the Claim |
|
|
262
265
|
| self.connectionSecret | Map | The name, namespace, and resourceName to use when generating the connection secret in Crossplane v2 |
|
|
263
|
-
| self.connection | Map | The composite desired connection
|
|
264
|
-
| self.connection.observed | Map | The composite observed connection
|
|
266
|
+
| self.connection | Map | The composite desired connection details |
|
|
267
|
+
| self.connection.observed | Map | The composite observed connection details |
|
|
265
268
|
| self.ready | Boolean | The composite desired ready state |
|
|
266
269
|
|
|
267
270
|
The BaseComposite also provides access to the following Crossplane Function level features:
|
|
@@ -278,9 +281,9 @@ The BaseComposite also provides access to the following Crossplane Function leve
|
|
|
278
281
|
| self.environment | Map | The response environment, initialized from the request context environment |
|
|
279
282
|
| self.requireds | Requireds | Request and read additional local Kubernetes resources |
|
|
280
283
|
| self.resources | Resources | Define and process composed resources |
|
|
281
|
-
| self.unknownsFatal | Boolean | Terminate the composition if already created resources are assigned unknown values, default True |
|
|
282
284
|
| self.usages| Boolean | Generate Crossplane Usages for resource dependencies, default False |
|
|
283
285
|
| self.autoReady | Boolean | Perform auto ready processing on all composed resources, default True |
|
|
286
|
+
| self.unknownsFatal | Boolean | Terminate the composition if already created resources are assigned unknown values, default False |
|
|
284
287
|
|
|
285
288
|
### Composed Resources
|
|
286
289
|
|
|
@@ -305,9 +308,11 @@ Resource class:
|
|
|
305
308
|
| Resource.conditions | Conditions | The resource conditions |
|
|
306
309
|
| Resource.connection | Map | The resource observed connection details |
|
|
307
310
|
| Resource.ready | Boolean | The resource ready state |
|
|
308
|
-
| Resource.
|
|
311
|
+
| Resource.addDependency | Method | Add another composed resource as a dependency |
|
|
312
|
+
| Resource.setReadyCondition | Method | Set Resource.ready to the Ready Condition status |
|
|
309
313
|
| Resource.usages | Boolean | Generate Crossplane Usages for this resource, default is Composite.autoReady |
|
|
310
314
|
| Resource.autoReady | Boolean | Perform auto ready processing on this resource, default is Composite.autoReady |
|
|
315
|
+
| Resource.unknownsFatal | Boolean | Terminate the composition if this resource has been created and is assigned unknown values, default is Composite.unknownsFatal |
|
|
311
316
|
|
|
312
317
|
### Required Resources
|
|
313
318
|
|
|
@@ -406,28 +411,34 @@ $ pip install crossplane-function-pythonic
|
|
|
406
411
|
Then to render function-pythonic Compositions, use the `function-pythonic render ...`
|
|
407
412
|
command.
|
|
408
413
|
```shell
|
|
409
|
-
$ function-pythonic render
|
|
410
|
-
usage: Crossplane Function Pythonic render [-h] [--debug] [--log-name-width WIDTH] [--
|
|
411
|
-
[--allow-oversize-protos] [--
|
|
412
|
-
[--
|
|
413
|
-
[--
|
|
414
|
-
|
|
414
|
+
$ function-pythonic render --help
|
|
415
|
+
usage: Crossplane Function Pythonic render [-h] [--debug] [--log-name-width WIDTH] [--logger-level LOGGER=LEVEL] [--python-path DIRECTORY]
|
|
416
|
+
[--render-unknowns] [--allow-oversize-protos] [--crossplane-v1] [--kube-context CONTEXT]
|
|
417
|
+
[--context-files KEY=PATH] [--context-values KEY=VALUE] [--observed-resources PATH]
|
|
418
|
+
[--required-resources PATH] [--secret-store PATH] [--include-full-xr] [--include-connection-xr]
|
|
419
|
+
[--include-function-results] [--include-context]
|
|
420
|
+
COMPOSITE [COMPOSITION]
|
|
415
421
|
|
|
416
422
|
positional arguments:
|
|
417
|
-
|
|
418
|
-
|
|
423
|
+
COMPOSITE A YAML file containing the Composite resource to render, or kind:apiVersion:namespace:name of cluster Composite.
|
|
424
|
+
COMPOSITION A YAML file containing the Composition resource, or the complete path of a function-pythonic BaseComposite subclass.
|
|
419
425
|
|
|
420
426
|
options:
|
|
421
427
|
-h, --help show this help message and exit
|
|
422
428
|
--debug, -d Emit debug logs.
|
|
423
429
|
--log-name-width WIDTH
|
|
424
430
|
Width of the logger name in the log output, default 40.
|
|
431
|
+
--logger-level LOGGER=LEVEL
|
|
432
|
+
Logger level, for example: botocore.hooks=INFO
|
|
425
433
|
--python-path DIRECTORY
|
|
426
434
|
Filing system directories to add to the python path.
|
|
427
435
|
--render-unknowns, -u
|
|
428
436
|
Render resources with unknowns, useful during local development.
|
|
429
437
|
--allow-oversize-protos
|
|
430
438
|
Allow oversized protobuf messages
|
|
439
|
+
--crossplane-v1 Enable Crossplane V1 compatibility mode
|
|
440
|
+
--kube-context, -k CONTEXT
|
|
441
|
+
The kubectl context to use to obtain external resources from, such as required resources, connections, etc.
|
|
431
442
|
--context-files KEY=PATH
|
|
432
443
|
Context key-value pairs to pass to the Function pipeline. Values must be files containing YAML/JSON.
|
|
433
444
|
--context-values KEY=VALUE
|
|
@@ -443,7 +454,7 @@ options:
|
|
|
443
454
|
--include-connection-xr
|
|
444
455
|
Include the Composite connection values in the rendered output as a resource of kind: Connection.
|
|
445
456
|
--include-function-results, -r
|
|
446
|
-
Include informational and warning messages from Functions in the rendered output as resources of kind: Result
|
|
457
|
+
Include informational and warning messages from Functions in the rendered output as resources of kind: Result.
|
|
447
458
|
--include-context, -c
|
|
448
459
|
Include the context in the rendered output as a resource of kind: Context.
|
|
449
460
|
```
|
|
@@ -579,7 +590,7 @@ kind: Function
|
|
|
579
590
|
metadata:
|
|
580
591
|
name: function-pythonic
|
|
581
592
|
spec:
|
|
582
|
-
package: xpkg.upbound.io/crossplane-contrib/function-pythonic:v0.
|
|
593
|
+
package: xpkg.upbound.io/crossplane-contrib/function-pythonic:v0.4.0
|
|
583
594
|
runtimeConfigRef:
|
|
584
595
|
name: function-pythonic
|
|
585
596
|
---
|
|
@@ -663,7 +674,7 @@ data:
|
|
|
663
674
|
from crossplane.pythonic import BaseComposite
|
|
664
675
|
class GreetingComposite(BaseComposite):
|
|
665
676
|
def compose(self):
|
|
666
|
-
cm = self.resources.ConfigMap('
|
|
677
|
+
cm = self.resources.ConfigMap('ConfigMap', 'v1')
|
|
667
678
|
cm.data.greeting = f"Hello, {self.parameters.who}!"
|
|
668
679
|
```
|
|
669
680
|
```yaml
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# This is set at build time, using "hatch version"
|
|
2
|
-
__version__ = "0.
|
|
2
|
+
__version__ = "0.4.0"
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
|
|
2
|
+
def resource_ready(resource):
|
|
3
|
+
if not resource.observed:
|
|
4
|
+
return None
|
|
5
|
+
return _checks.get((resource.observed.apiVersion, resource.observed.kind), _check_default).ready(resource)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ReadyCondition:
|
|
9
|
+
def ready(self, resource):
|
|
10
|
+
ready = resource.conditions.Ready
|
|
11
|
+
if not ready._find_condition():
|
|
12
|
+
return None
|
|
13
|
+
if ready.status:
|
|
14
|
+
return resource.observed.metadata.name
|
|
15
|
+
if ready.reason:
|
|
16
|
+
return resource.status.notReadyCondition[ready.reason]
|
|
17
|
+
return resource.status.notReadyCondition
|
|
18
|
+
|
|
19
|
+
_checks = {}
|
|
20
|
+
_check_default = ReadyCondition()
|
|
21
|
+
|
|
22
|
+
class Check:
|
|
23
|
+
@classmethod
|
|
24
|
+
def __init_subclass__(cls, **kwargs):
|
|
25
|
+
super().__init_subclass__(**kwargs)
|
|
26
|
+
if hasattr(cls, 'apiVersion'):
|
|
27
|
+
_checks[(cls.apiVersion, cls.__name__)] = cls()
|
|
28
|
+
|
|
29
|
+
def ready(self, resource):
|
|
30
|
+
raise NotImplementedError()
|
|
31
|
+
|
|
32
|
+
class AlwaysReady(Check):
|
|
33
|
+
def ready(self, resource):
|
|
34
|
+
return resource.observed.metadata.name
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class ClusterRole(AlwaysReady):
|
|
38
|
+
apiVersion = 'rbac.authorization.k8s.io/v1'
|
|
39
|
+
|
|
40
|
+
class ClusterRoleBinding(AlwaysReady):
|
|
41
|
+
apiVersion = 'rbac.authorization.k8s.io/v1'
|
|
42
|
+
|
|
43
|
+
class ConfigMap(AlwaysReady):
|
|
44
|
+
apiVersion = 'v1'
|
|
45
|
+
|
|
46
|
+
class CronJob(Check):
|
|
47
|
+
apiVersion = 'batch/v1'
|
|
48
|
+
def ready(self, resource):
|
|
49
|
+
if resource.observed.spec.suspend and len(resource.observed.spec.suspend):
|
|
50
|
+
return resource.observed.metadata.name
|
|
51
|
+
if not resource.status.lastScheduleTime:
|
|
52
|
+
return resource.status.lastScheduleTime
|
|
53
|
+
if resource.status.active:
|
|
54
|
+
return resource.observed.metadata.name
|
|
55
|
+
if not resource.status.lastSuccessfulTime:
|
|
56
|
+
return resource.status.lastSuccessfulTime
|
|
57
|
+
if str(resource.status.lastSuccessfulTime) < str(resource.status.lastScheduleTime):
|
|
58
|
+
return resource.status.successfulBeforeSchedule
|
|
59
|
+
return resource.observed.metadata.name
|
|
60
|
+
|
|
61
|
+
class DaemonSet(Check):
|
|
62
|
+
apiVersion = 'apps/v1'
|
|
63
|
+
def ready(self, resource):
|
|
64
|
+
scheduled = resource.status.desiredNumberScheduled
|
|
65
|
+
if not scheduled:
|
|
66
|
+
return scheduled
|
|
67
|
+
for field in ('numberReady', 'updatedNumberScheduled', 'numberAvailable'):
|
|
68
|
+
value = resource.status[field]
|
|
69
|
+
if not value:
|
|
70
|
+
return value
|
|
71
|
+
if scheduled != value:
|
|
72
|
+
return resource.status[f"{field}NotScheduled"]
|
|
73
|
+
return resource.observed.metadata.name
|
|
74
|
+
|
|
75
|
+
class Deployment(Check):
|
|
76
|
+
apiVersion = 'apps/v1'
|
|
77
|
+
def ready(self, resource):
|
|
78
|
+
replicas = resource.observed.spec.replicas or 1
|
|
79
|
+
for field in ('updatedReplicas', 'availableReplicas'):
|
|
80
|
+
value = resource.status[field]
|
|
81
|
+
if not value:
|
|
82
|
+
return value
|
|
83
|
+
if replicas != value:
|
|
84
|
+
return resource.status[F"{field}NotReplicas"]
|
|
85
|
+
available = resource.conditions.Available
|
|
86
|
+
if not available:
|
|
87
|
+
return resource.status.notAvailable
|
|
88
|
+
if not available.status:
|
|
89
|
+
if available.reason:
|
|
90
|
+
return resource.status.notAvailable[available.reason]
|
|
91
|
+
return resource.status.notAvailable
|
|
92
|
+
return resource.observed.metadata.name
|
|
93
|
+
|
|
94
|
+
class HorizontalPodAutoscaler(Check):
|
|
95
|
+
apiVersion = 'autoscaling/v2'
|
|
96
|
+
def ready(self, resource):
|
|
97
|
+
for type in ('FailedGetScale', 'FailedUpdateScale', 'FailedGetResourceMetric', 'InvalidSelector'):
|
|
98
|
+
if resource.conditions[type].status:
|
|
99
|
+
return resource.status[f"is{type}"]
|
|
100
|
+
for type in ('ScalingActive', 'ScalingLimited'):
|
|
101
|
+
if resource.conditions[type].status:
|
|
102
|
+
return resource.observed.metadata.name
|
|
103
|
+
return resource.status.notScalingActiveOrLimiited
|
|
104
|
+
|
|
105
|
+
class Ingress(Check):
|
|
106
|
+
apiVersion = 'networking.k8s.io/v1'
|
|
107
|
+
def ready(self, resource):
|
|
108
|
+
if not len(resource.status.loadBalancer.ingress):
|
|
109
|
+
return resource.status.noLoadBalanceIngresses
|
|
110
|
+
return resource.observed.metadata.name
|
|
111
|
+
|
|
112
|
+
class Job(Check):
|
|
113
|
+
apiVersion = 'batch/v1'
|
|
114
|
+
def ready(self, resource):
|
|
115
|
+
for type in ('Failed', 'Suspended'):
|
|
116
|
+
if resource.conditions[type].status:
|
|
117
|
+
return resource.status[f"is{type}"]
|
|
118
|
+
complete = resource.conditions.Complete
|
|
119
|
+
if not complete:
|
|
120
|
+
return resource.status.notComplete
|
|
121
|
+
if not complete.status:
|
|
122
|
+
if complete.reason:
|
|
123
|
+
return resource.status.notComplete[complete.reason]
|
|
124
|
+
return resource.status.notComplete
|
|
125
|
+
return resource.observed.metadata.name
|
|
126
|
+
|
|
127
|
+
class Namespace(AlwaysReady):
|
|
128
|
+
apiVersion = 'v1'
|
|
129
|
+
|
|
130
|
+
class PersistentVolumeClaim(Check):
|
|
131
|
+
apiVersion = 'v1'
|
|
132
|
+
def ready(self, resource):
|
|
133
|
+
if resource.status.phase != 'Bound':
|
|
134
|
+
return resource.status.phaseNotBound
|
|
135
|
+
return resource.observed.metadata.name
|
|
136
|
+
|
|
137
|
+
class Pod(Check):
|
|
138
|
+
apiVersion = 'v1'
|
|
139
|
+
def ready(self, resource):
|
|
140
|
+
if resource.status.phase == 'Succeeded':
|
|
141
|
+
return resource.observed.metadata.name
|
|
142
|
+
if resource.status.phase == 'Running':
|
|
143
|
+
if resource.observed.spec.restartPolicy == 'Always':
|
|
144
|
+
if resource.conditions.Ready.status:
|
|
145
|
+
return resource.observed.metadata.name
|
|
146
|
+
return resource.status.notSucceededOrRunning
|
|
147
|
+
|
|
148
|
+
class ReplicaSet(Check):
|
|
149
|
+
apiVersion = 'v1'
|
|
150
|
+
def ready(self, resource):
|
|
151
|
+
if int(resource.status.observedGeneration) < int(resource.observed.metadata.generation):
|
|
152
|
+
return resource.status.priorObservedGeneration
|
|
153
|
+
if resource.conditions.ReplicaFailure.status:
|
|
154
|
+
if resource.conditions.ReplicaFailure.reason:
|
|
155
|
+
return resource.status.isReplicaFailure[resource.conditions.ReplicaFailure.reason]
|
|
156
|
+
return resource.status.isReplicaFailure
|
|
157
|
+
if int(resource.status.availableReplicas) < int(resource.observed.spec.replicas or 1):
|
|
158
|
+
return resource.status.tooFewavailableReplicas
|
|
159
|
+
return resource.observed.metadata.name
|
|
160
|
+
|
|
161
|
+
class Role(AlwaysReady):
|
|
162
|
+
apiVersion = 'rbac.authorization.k8s.io/v1'
|
|
163
|
+
|
|
164
|
+
class RoleBinding(AlwaysReady):
|
|
165
|
+
apiVersion = 'rbac.authorization.k8s.io/v1'
|
|
166
|
+
|
|
167
|
+
class Secret(AlwaysReady):
|
|
168
|
+
apiVersion = 'v1'
|
|
169
|
+
|
|
170
|
+
class Service(Check):
|
|
171
|
+
apiVersion = 'v1'
|
|
172
|
+
def ready(self, resource):
|
|
173
|
+
if resource.observed.spec.type != 'LoadBalancer':
|
|
174
|
+
return resource.observed.metadata.name
|
|
175
|
+
if not len(resource.status.loadBalancer.ingress):
|
|
176
|
+
return resource.status.noLoadBalancerIngresses
|
|
177
|
+
return resource.observed.metadata.name
|
|
178
|
+
|
|
179
|
+
class ServiceAccount(AlwaysReady):
|
|
180
|
+
apiVersion = 'v1'
|
|
181
|
+
|
|
182
|
+
class StatefulSet(Check):
|
|
183
|
+
apiVersion = 'apps/v1'
|
|
184
|
+
def ready(self, resource):
|
|
185
|
+
replicas = resource.observed.spec.replicas or 1
|
|
186
|
+
for field in ('readyReplicas', 'currentReplicas'):
|
|
187
|
+
value = resource.status[field]
|
|
188
|
+
if not value:
|
|
189
|
+
return value
|
|
190
|
+
if replicas != value:
|
|
191
|
+
return resource.status[F"{field}NotReplicas"]
|
|
192
|
+
if resource.status.currentRevision != resource.status.updateRevision:
|
|
193
|
+
return resource.status.currentRevisionNotUpdateReivsion
|
|
194
|
+
return resource.observed.metadata.name
|