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.
Files changed (161) hide show
  1. crossplane_function_pythonic-0.3.0/README.md → crossplane_function_pythonic-0.4.0/PKG-INFO +86 -25
  2. crossplane_function_pythonic-0.3.0/PKG-INFO → crossplane_function_pythonic-0.4.0/README.md +60 -49
  3. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/crossplane/pythonic/__about__.py +1 -1
  4. crossplane_function_pythonic-0.4.0/crossplane/pythonic/auto_ready.py +194 -0
  5. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/crossplane/pythonic/command.py +12 -0
  6. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/crossplane/pythonic/composite.py +98 -69
  7. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/crossplane/pythonic/function.py +14 -5
  8. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/crossplane/pythonic/protobuf.py +37 -5
  9. crossplane_function_pythonic-0.4.0/crossplane/pythonic/render.py +630 -0
  10. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/aks-cluster/aks/kubernetescluster.py +1 -1
  11. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/aks-cluster/aks/resourcegroup.py +1 -3
  12. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/aks-cluster/cluster-function-pythonic.yaml +1 -1
  13. crossplane_function_pythonic-0.4.0/examples/aks-cluster/render.sh +4 -0
  14. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/connection-details-composition/composition.yaml +2 -2
  15. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/connection-details-composition/render.sh +0 -2
  16. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/connections/composition.yaml +1 -1
  17. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/eks-cluster/composition-v2.yaml +11 -11
  18. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/eks-cluster/composition.yaml +11 -11
  19. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/eks-cluster/render-v2.sh +0 -1
  20. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/eks-cluster/render.sh +0 -1
  21. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/filing-system/vcluster.py +3 -3
  22. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/conditions/render.sh +0 -1
  23. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/context/render.sh +0 -1
  24. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/fromYaml/render.sh +0 -1
  25. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/getComposedResource/composition.yaml +2 -2
  26. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/getComposedResource/render.sh +0 -1
  27. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/getCompositeResource/composition.yaml +1 -1
  28. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/getCompositeResource/render.sh +0 -1
  29. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/getCredentialData/render.sh +0 -1
  30. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/getResourceCondition/render.sh +0 -1
  31. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/include/composition.yaml +1 -1
  32. crossplane_function_pythonic-0.4.0/examples/function-go-templating/functions/include/render.sh +3 -0
  33. crossplane_function_pythonic-0.4.0/examples/function-go-templating/functions/toYaml/render.sh +3 -0
  34. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/inline/composition.yaml +2 -2
  35. crossplane_function_pythonic-0.4.0/examples/function-go-templating/inline/render.sh +3 -0
  36. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/recursive/composition-real.yaml +1 -1
  37. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/recursive/composition-wrapper.yaml +1 -1
  38. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/recursive/render.sh +0 -3
  39. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/required-resources/composition.yaml +2 -2
  40. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/required-resources/render.sh +0 -1
  41. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-sequencer/composition.yaml +1 -1
  42. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-sequencer/render.sh +0 -1
  43. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/get-started-app/composition.yaml +2 -2
  44. crossplane_function_pythonic-0.4.0/examples/get-started-app/observed.yaml +53 -0
  45. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/get-started-app/render.sh +0 -1
  46. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/helm-copy-secret/render.sh +0 -1
  47. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/helm-copy-secret/vcluster.py +3 -3
  48. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/import-existing-vpc/composition.yaml +1 -1
  49. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/import-existing-vpc/render.sh +0 -3
  50. crossplane_function_pythonic-0.4.0/examples/run-all.sh +3 -0
  51. 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
  52. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/usages-extra/composition.yaml +2 -2
  53. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/usages-extra/render.sh +0 -1
  54. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/pyproject.toml +5 -3
  55. crossplane_function_pythonic-0.3.0/crossplane/pythonic/auto_ready.py +0 -153
  56. crossplane_function_pythonic-0.3.0/crossplane/pythonic/render.py +0 -462
  57. crossplane_function_pythonic-0.3.0/examples/.dev/functions.yaml +0 -13
  58. crossplane_function_pythonic-0.3.0/examples/aks-cluster/functions.yaml +0 -10
  59. crossplane_function_pythonic-0.3.0/examples/aks-cluster/render.sh +0 -10
  60. crossplane_function_pythonic-0.3.0/examples/connection-details-composition/functions.yaml +0 -8
  61. crossplane_function_pythonic-0.3.0/examples/eks-cluster/functions.yaml +0 -8
  62. crossplane_function_pythonic-0.3.0/examples/filing-system/function.yaml +0 -10
  63. crossplane_function_pythonic-0.3.0/examples/function-go-templating/conditions/functions.yaml +0 -10
  64. crossplane_function_pythonic-0.3.0/examples/function-go-templating/context/functions.yaml +0 -10
  65. crossplane_function_pythonic-0.3.0/examples/function-go-templating/functions/fromYaml/functions.yaml +0 -9
  66. crossplane_function_pythonic-0.3.0/examples/function-go-templating/functions/getComposedResource/functions.yaml +0 -9
  67. crossplane_function_pythonic-0.3.0/examples/function-go-templating/functions/getCompositeResource/functions.yaml +0 -9
  68. crossplane_function_pythonic-0.3.0/examples/function-go-templating/functions/getCredentialData/functions.yaml +0 -9
  69. crossplane_function_pythonic-0.3.0/examples/function-go-templating/functions/getResourceCondition/functions.yaml +0 -9
  70. crossplane_function_pythonic-0.3.0/examples/function-go-templating/functions/include/functions.yaml +0 -9
  71. crossplane_function_pythonic-0.3.0/examples/function-go-templating/functions/include/render.sh +0 -4
  72. crossplane_function_pythonic-0.3.0/examples/function-go-templating/functions/toYaml/functions.yaml +0 -9
  73. crossplane_function_pythonic-0.3.0/examples/function-go-templating/functions/toYaml/render.sh +0 -4
  74. crossplane_function_pythonic-0.3.0/examples/function-go-templating/inline/functions.yaml +0 -9
  75. crossplane_function_pythonic-0.3.0/examples/function-go-templating/inline/render.sh +0 -4
  76. crossplane_function_pythonic-0.3.0/examples/function-go-templating/recursive/functions.yaml +0 -9
  77. crossplane_function_pythonic-0.3.0/examples/function-go-templating/required-resources/functions.yaml +0 -9
  78. crossplane_function_pythonic-0.3.0/examples/function-sequencer/functions.yaml +0 -8
  79. crossplane_function_pythonic-0.3.0/examples/get-started-app/functions.yaml +0 -8
  80. crossplane_function_pythonic-0.3.0/examples/helm-copy-secret/functions.yaml +0 -8
  81. crossplane_function_pythonic-0.3.0/examples/import-existing-vpc/functions.yaml +0 -8
  82. crossplane_function_pythonic-0.3.0/examples/single-purpose/functions.yaml +0 -8
  83. crossplane_function_pythonic-0.3.0/examples/single-purpose/render.sh +0 -4
  84. crossplane_function_pythonic-0.3.0/examples/usages-extra/functions.yaml +0 -9
  85. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/.gitignore +0 -0
  86. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/LICENSE +0 -0
  87. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/crossplane/pythonic/__init__.py +0 -0
  88. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/crossplane/pythonic/__main__.py +0 -0
  89. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/crossplane/pythonic/grpc.py +0 -0
  90. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/crossplane/pythonic/main.py +0 -0
  91. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/crossplane/pythonic/packages.py +0 -0
  92. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/crossplane/pythonic/version.py +0 -0
  93. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/aks-cluster/README.md +0 -0
  94. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/aks-cluster/composition.yaml +0 -0
  95. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/aks-cluster/definition.yaml +0 -0
  96. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/aks-cluster/install.sh +0 -0
  97. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/aks-cluster/kustomization.yaml +0 -0
  98. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/aks-cluster/providers.yaml +0 -0
  99. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/aks-cluster/xr.yaml +0 -0
  100. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/connection-details-composition/access-keys.yaml +0 -0
  101. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/connection-details-composition/definition.yaml +0 -0
  102. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/connection-details-composition/secrets.yaml +0 -0
  103. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/connection-details-composition/user.yaml +0 -0
  104. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/connection-details-composition/xr.yaml +0 -0
  105. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/connections/composite-connection.yaml +0 -0
  106. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/connections/rds-connection.yaml +0 -0
  107. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/connections/rds-observed.yaml +0 -0
  108. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/connections/render.sh +0 -0
  109. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/connections/step-credential.yaml +0 -0
  110. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/connections/xr.yaml +0 -0
  111. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/eks-cluster/definition.yaml +0 -0
  112. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/eks-cluster/xr.yaml +0 -0
  113. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/filing-system/README.md +0 -0
  114. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/filing-system/composition.yaml +0 -0
  115. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/filing-system/definition.yaml +0 -0
  116. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/filing-system/kustomization.yaml +0 -0
  117. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/filing-system/runtime.yaml +0 -0
  118. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/filing-system/vcluster.yaml +0 -0
  119. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/conditions/composition.yaml +0 -0
  120. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/conditions/xr.yaml +0 -0
  121. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/conditions/xrd.yaml +0 -0
  122. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/context/composition.yaml +0 -0
  123. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/context/environmentConfigs.yaml +0 -0
  124. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/context/xr.yaml +0 -0
  125. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/context/xrd.yaml +0 -0
  126. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/fromYaml/composition.yaml +0 -0
  127. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/fromYaml/xr.yaml +0 -0
  128. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/getComposedResource/observed.yaml +0 -0
  129. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/getComposedResource/xr.yaml +0 -0
  130. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/getCompositeResource/xr.yaml +0 -0
  131. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/getCredentialData/composition.yaml +0 -0
  132. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/getCredentialData/credentials.yaml +0 -0
  133. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/getCredentialData/xr.yaml +0 -0
  134. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/getResourceCondition/composition.yaml +0 -0
  135. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/getResourceCondition/observed.yaml +0 -0
  136. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/getResourceCondition/xr.yaml +0 -0
  137. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/include/xr.yaml +0 -0
  138. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/toYaml/composition.yaml +0 -0
  139. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/functions/toYaml/xr.yaml +0 -0
  140. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/inline/xr.yaml +0 -0
  141. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/recursive/xr.yaml +0 -0
  142. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/required-resources/required-resources.yaml +0 -0
  143. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-go-templating/required-resources/xr.yaml +0 -0
  144. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-sequencer/observed.yaml +0 -0
  145. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-sequencer/sequencer.py +0 -0
  146. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/function-sequencer/xr.yaml +0 -0
  147. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/get-started-app/definition.yaml +0 -0
  148. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/get-started-app/xr.yaml +0 -0
  149. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/helm-copy-secret/composition.yaml +0 -0
  150. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/helm-copy-secret/kustomization.yaml +0 -0
  151. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/helm-copy-secret/xr.yaml +0 -0
  152. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/helm-copy-secret/xrd.yaml +0 -0
  153. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/import-existing-vpc/README.md +0 -0
  154. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/import-existing-vpc/definition.yaml +0 -0
  155. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/import-existing-vpc/observed.yaml +0 -0
  156. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/import-existing-vpc/provider-ec2.yaml +0 -0
  157. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/import-existing-vpc/xr.yaml +0 -0
  158. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/single-purpose/xr.yaml +0 -0
  159. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/usages-extra/extraResources.yaml +0 -0
  160. {crossplane_function_pythonic-0.3.0 → crossplane_function_pythonic-0.4.0}/examples/usages-extra/observedResources.yaml +0 -0
  161. {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', 'VPC')
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.3.0
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.3.0
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
- ```yaml
108
- vpc = self.resources.VPC('ec2.aws.crossplane.io/v1beta1', 'VPC')
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', 'Subnet')
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
- ```yaml
187
+ ```python
135
188
  self.usages = True
136
189
 
137
- vpc = self.resources.VPC('ec2.aws.crossplane.io/v1beta1', 'VPC')
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', 'Subnet')
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', kind='VPC')
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 detials |
240
- | self.connection.observed | Map | The composite observed connection detials |
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.unknownsFatal | Boolean | Terminate the composition if this resource has been created and is assigned unknown values, default is Composite.unknownsFatal |
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 -h
386
- usage: Crossplane Function Pythonic render [-h] [--debug] [--log-name-width WIDTH] [--python-path DIRECTORY] [--render-unknowns]
387
- [--allow-oversize-protos] [--context-files KEY=PATH] [--context-values KEY=VALUE]
388
- [--observed-resources PATH] [--required-resources PATH] [--secret-store PATH] [--include-full-xr]
389
- [--include-connection-xr] [--include-function-results] [--include-context]
390
- PATH [PATH/CLASS]
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
- PATH A YAML file containing the Composite resource to render.
394
- PATH/CLASS A YAML file containing the Composition resource or the complete path of a function=-pythonic BaseComposite subclass.
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.3.0
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('v1', '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', 'VPC')
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.3.0
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.3.0
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
- ```yaml
132
- vpc = self.resources.VPC('ec2.aws.crossplane.io/v1beta1', 'VPC')
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', 'Subnet')
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
- ```yaml
161
+ ```python
159
162
  self.usages = True
160
163
 
161
- vpc = self.resources.VPC('ec2.aws.crossplane.io/v1beta1', 'VPC')
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', 'Subnet')
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', kind='VPC')
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 detials |
264
- | self.connection.observed | Map | The composite observed connection detials |
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.unknownsFatal | Boolean | Terminate the composition if this resource has been created and is assigned unknown values, default is Composite.unknownsFatal |
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 -h
410
- usage: Crossplane Function Pythonic render [-h] [--debug] [--log-name-width WIDTH] [--python-path DIRECTORY] [--render-unknowns]
411
- [--allow-oversize-protos] [--context-files KEY=PATH] [--context-values KEY=VALUE]
412
- [--observed-resources PATH] [--required-resources PATH] [--secret-store PATH] [--include-full-xr]
413
- [--include-connection-xr] [--include-function-results] [--include-context]
414
- PATH [PATH/CLASS]
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
- PATH A YAML file containing the Composite resource to render.
418
- PATH/CLASS A YAML file containing the Composition resource or the complete path of a function=-pythonic BaseComposite subclass.
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.3.0
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('v1', '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.3.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