crossplane-function-pythonic 0.0.10__tar.gz → 0.1.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 (116) hide show
  1. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/.gitignore +1 -0
  2. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/PKG-INFO +24 -2
  3. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/README.md +23 -1
  4. crossplane_function_pythonic-0.1.0/crossplane/pythonic/__init__.py +16 -0
  5. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/crossplane/pythonic/composite.py +68 -18
  6. crossplane_function_pythonic-0.1.0/crossplane/pythonic/function.py +359 -0
  7. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/crossplane/pythonic/main.py +6 -1
  8. crossplane_function_pythonic-0.1.0/crossplane/pythonic/packages.py +148 -0
  9. crossplane_function_pythonic-0.1.0/crossplane/pythonic/protobuf.py +1278 -0
  10. crossplane_function_pythonic-0.1.0/examples/aks-cluster/README.md +129 -0
  11. crossplane_function_pythonic-0.1.0/examples/aks-cluster/aks/kubernetescluster.py +29 -0
  12. crossplane_function_pythonic-0.1.0/examples/aks-cluster/aks/resourcegroup.py +14 -0
  13. crossplane_function_pythonic-0.1.0/examples/aks-cluster/cluster-function-pythonic.yaml +63 -0
  14. crossplane_function_pythonic-0.1.0/examples/aks-cluster/composition.yaml +24 -0
  15. crossplane_function_pythonic-0.1.0/examples/aks-cluster/definition.yaml +45 -0
  16. crossplane_function_pythonic-0.1.0/examples/aks-cluster/functions.yaml +10 -0
  17. crossplane_function_pythonic-0.1.0/examples/aks-cluster/install.sh +13 -0
  18. crossplane_function_pythonic-0.1.0/examples/aks-cluster/kustomization.yaml +20 -0
  19. crossplane_function_pythonic-0.1.0/examples/aks-cluster/providers.yaml +14 -0
  20. crossplane_function_pythonic-0.1.0/examples/aks-cluster/render.sh +9 -0
  21. crossplane_function_pythonic-0.1.0/examples/aks-cluster/xr.yaml +16 -0
  22. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/eks-cluster/composition.yaml +2 -0
  23. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/eks-cluster/xr.yaml +1 -0
  24. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/conditions/composition.yaml +6 -6
  25. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/inline/composition.yaml +1 -1
  26. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/get-started-app/composition.yaml +2 -2
  27. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/helm-copy-secret/vcluster.py +1 -1
  28. crossplane_function_pythonic-0.1.0/examples/usages-extra/composition.yaml +26 -0
  29. crossplane_function_pythonic-0.1.0/examples/usages-extra/extraResources.yaml +7 -0
  30. crossplane_function_pythonic-0.1.0/examples/usages-extra/functions.yaml +9 -0
  31. crossplane_function_pythonic-0.1.0/examples/usages-extra/observedResources.yaml +6 -0
  32. crossplane_function_pythonic-0.1.0/examples/usages-extra/render.sh +3 -0
  33. crossplane_function_pythonic-0.1.0/examples/usages-extra/xr.yaml +6 -0
  34. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/pyproject.toml +7 -4
  35. crossplane_function_pythonic-0.0.10/crossplane/pythonic/__init__.py +0 -19
  36. crossplane_function_pythonic-0.0.10/crossplane/pythonic/function.py +0 -271
  37. crossplane_function_pythonic-0.0.10/crossplane/pythonic/packages.py +0 -157
  38. crossplane_function_pythonic-0.0.10/crossplane/pythonic/protobuf.py +0 -931
  39. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/LICENSE +0 -0
  40. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/.dev/functions.yaml +0 -0
  41. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/eks-cluster/composition-v2.yaml +0 -0
  42. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/eks-cluster/definition.yaml +0 -0
  43. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/eks-cluster/functions.yaml +0 -0
  44. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/eks-cluster/render-v2.sh +0 -0
  45. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/eks-cluster/render.sh +0 -0
  46. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/filing-system/README.md +0 -0
  47. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/filing-system/composition.yaml +0 -0
  48. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/filing-system/definition.yaml +0 -0
  49. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/filing-system/function.yaml +0 -0
  50. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/filing-system/kustomization.yaml +0 -0
  51. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/filing-system/runtime.yaml +0 -0
  52. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/filing-system/vcluster.py +0 -0
  53. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/filing-system/vcluster.yaml +0 -0
  54. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/conditions/functions.yaml +0 -0
  55. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/conditions/render.sh +0 -0
  56. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/conditions/xr.yaml +0 -0
  57. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/conditions/xrd.yaml +0 -0
  58. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/context/composition.yaml +0 -0
  59. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/context/environmentConfigs.yaml +0 -0
  60. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/context/functions.yaml +0 -0
  61. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/context/render.sh +0 -0
  62. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/context/xr.yaml +0 -0
  63. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/context/xrd.yaml +0 -0
  64. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/extra-resources/composition.yaml +0 -0
  65. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/extra-resources/extraResources.yaml +0 -0
  66. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/extra-resources/functions.yaml +0 -0
  67. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/extra-resources/render.sh +0 -0
  68. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/extra-resources/xr.yaml +0 -0
  69. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/functions/fromYaml/composition.yaml +0 -0
  70. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/functions/fromYaml/functions.yaml +0 -0
  71. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/functions/fromYaml/render.sh +0 -0
  72. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/functions/fromYaml/xr.yaml +0 -0
  73. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/functions/getComposedResource/composition.yaml +0 -0
  74. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/functions/getComposedResource/functions.yaml +0 -0
  75. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/functions/getComposedResource/observed.yaml +0 -0
  76. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/functions/getComposedResource/render.sh +0 -0
  77. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/functions/getComposedResource/xr.yaml +0 -0
  78. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/functions/getCompositeResource/composition.yaml +0 -0
  79. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/functions/getCompositeResource/functions.yaml +0 -0
  80. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/functions/getCompositeResource/render.sh +0 -0
  81. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/functions/getCompositeResource/xr.yaml +0 -0
  82. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/functions/getResourceCondition/composition.yaml +0 -0
  83. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/functions/getResourceCondition/functions.yaml +0 -0
  84. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/functions/getResourceCondition/observed.yaml +0 -0
  85. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/functions/getResourceCondition/render.sh +0 -0
  86. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/functions/getResourceCondition/xr.yaml +0 -0
  87. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/functions/include/composition.yaml +0 -0
  88. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/functions/include/functions.yaml +0 -0
  89. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/functions/include/render.sh +0 -0
  90. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/functions/include/xr.yaml +0 -0
  91. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/functions/toYaml/composition.yaml +0 -0
  92. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/functions/toYaml/functions.yaml +0 -0
  93. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/functions/toYaml/render.sh +0 -0
  94. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/functions/toYaml/xr.yaml +0 -0
  95. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/inline/functions.yaml +0 -0
  96. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/inline/render.sh +0 -0
  97. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/inline/xr.yaml +0 -0
  98. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/recursive/composition-real.yaml +0 -0
  99. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/recursive/composition-wrapper.yaml +0 -0
  100. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/recursive/functions.yaml +0 -0
  101. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/recursive/render.sh +0 -0
  102. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/function-go-templating/recursive/xr.yaml +0 -0
  103. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/get-started-app/definition.yaml +0 -0
  104. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/get-started-app/functions.yaml +0 -0
  105. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/get-started-app/render.sh +0 -0
  106. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/get-started-app/xr.yaml +0 -0
  107. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/helm-copy-secret/composition.yaml +0 -0
  108. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/helm-copy-secret/functions.yaml +0 -0
  109. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/helm-copy-secret/kustomization.yaml +0 -0
  110. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/helm-copy-secret/render.sh +0 -0
  111. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/helm-copy-secret/run-function.sh +0 -0
  112. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/helm-copy-secret/xr.yaml +0 -0
  113. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/helm-copy-secret/xrd.yaml +0 -0
  114. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/single-purpose/functions.yaml +0 -0
  115. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/single-purpose/render.sh +0 -0
  116. {crossplane_function_pythonic-0.0.10 → crossplane_function_pythonic-0.1.0}/examples/single-purpose/xr.yaml +0 -0
@@ -214,3 +214,4 @@ __marimo__/
214
214
  crossplane/pythonic/__version__.py
215
215
  pocs/
216
216
  pythonic-packages/
217
+ tests/protobuf/pytest_pb2*
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: crossplane-function-pythonic
3
- Version: 0.0.10
3
+ Version: 0.1.0
4
4
  Summary: A Python centric Crossplane Function
5
5
  Project-URL: Documentation, https://github.com/fortra/function-pythonic#readme
6
6
  Project-URL: Issues, https://github.com/fortra/function-pythonic/issues
@@ -119,6 +119,26 @@ overridden for all composed resource by setting the Composite `self.unknownsFata
119
119
  to False, or at the individual composed resource level by setting the
120
120
  `Resource.unknownsFatal` field to False.
121
121
 
122
+ ## Usage Dependencies
123
+
124
+ function-pythonic can be configured to automatically create
125
+ [Crossplane Usages](https://docs.crossplane.io/latest/managed-resources/usages/)
126
+ dependencies between resources. Modifying the above VPC example with:
127
+ ```yaml
128
+ self.usages = True
129
+
130
+ vpc = self.resources.VPC('ec2.aws.crossplane.io/v1beta1', 'VPC')
131
+ vpc.spec.forProvider.region = 'us-east-1
132
+ vpc.spec.forProvider.cidrBlock = '10.0.0.0/16'
133
+
134
+ subnet = self.resources.SubnetA('ec2.aws.crossplane.io/v1beta1', 'Subnet')
135
+ subnet.spec.forProvider.region = 'us-east-1'
136
+ subnet.spec.forProvider.vpcId = vpc.status.atProvider.vpcId
137
+ subnet.spec.forProvider.availabilityZone = 'us-east-1a'
138
+ subnet.spec.forProvider.cidrBlock = '10.0.0.0/20'
139
+ ```
140
+ Will generate the appropriate Crossplane Usage resource.
141
+
122
142
  ## Pythonic access of Protobuf Messages
123
143
 
124
144
  All Protobuf messages are wrapped by a set of python classes which enable using
@@ -225,6 +245,7 @@ The BaseComposite also provides access to the following Crossplane Function leve
225
245
  | self.requireds | Requireds | Request and read additional local Kubernetes resources |
226
246
  | self.resources | Resources | Define and process composed resources |
227
247
  | self.unknownsFatal | Boolean | Terminate the composition if already created resources are assigned unknown values, default True |
248
+ | self.usages| Boolean | Generate Crossplane Usages for resource dependencies, default False |
228
249
  | self.autoReady | Boolean | Perform auto ready processing on all composed resources, default True |
229
250
 
230
251
  ### Composed Resources
@@ -251,6 +272,7 @@ Resource class:
251
272
  | Resource.connection | Connection | The resource connection details |
252
273
  | Resource.ready | Boolean | The resource ready state |
253
274
  | Resource.unknownsFatal | Boolean | Terminate the composition if this resource has been created and is assigned unknown values, default is Composite.unknownsFatal |
275
+ | Resource.usages | Boolean | Generate Crossplane Usages for this resource, default is Composite.autoReady |
254
276
  | Resource.autoReady | Boolean | Perform auto ready processing on this resource, default is Composite.autoReady |
255
277
 
256
278
  ### Required Resources (AKA Extra Resources)
@@ -390,7 +412,7 @@ spec:
390
412
  ```
391
413
  In one terminal session, run function-pythonic:
392
414
  ```shell
393
- $ function-pythonic --insecure --debug
415
+ $ function-pythonic --insecure --debug --render-unknowns
394
416
  [2025-08-21 15:32:37.966] grpc._cython.cygrpc [DEBUG ] Using AsyncIOEngine.POLLER as I/O engine
395
417
  ```
396
418
  In another terminal session, render the Composite:
@@ -95,6 +95,26 @@ overridden for all composed resource by setting the Composite `self.unknownsFata
95
95
  to False, or at the individual composed resource level by setting the
96
96
  `Resource.unknownsFatal` field to False.
97
97
 
98
+ ## Usage Dependencies
99
+
100
+ function-pythonic can be configured to automatically create
101
+ [Crossplane Usages](https://docs.crossplane.io/latest/managed-resources/usages/)
102
+ dependencies between resources. Modifying the above VPC example with:
103
+ ```yaml
104
+ self.usages = True
105
+
106
+ vpc = self.resources.VPC('ec2.aws.crossplane.io/v1beta1', 'VPC')
107
+ vpc.spec.forProvider.region = 'us-east-1
108
+ vpc.spec.forProvider.cidrBlock = '10.0.0.0/16'
109
+
110
+ subnet = self.resources.SubnetA('ec2.aws.crossplane.io/v1beta1', 'Subnet')
111
+ subnet.spec.forProvider.region = 'us-east-1'
112
+ subnet.spec.forProvider.vpcId = vpc.status.atProvider.vpcId
113
+ subnet.spec.forProvider.availabilityZone = 'us-east-1a'
114
+ subnet.spec.forProvider.cidrBlock = '10.0.0.0/20'
115
+ ```
116
+ Will generate the appropriate Crossplane Usage resource.
117
+
98
118
  ## Pythonic access of Protobuf Messages
99
119
 
100
120
  All Protobuf messages are wrapped by a set of python classes which enable using
@@ -201,6 +221,7 @@ The BaseComposite also provides access to the following Crossplane Function leve
201
221
  | self.requireds | Requireds | Request and read additional local Kubernetes resources |
202
222
  | self.resources | Resources | Define and process composed resources |
203
223
  | self.unknownsFatal | Boolean | Terminate the composition if already created resources are assigned unknown values, default True |
224
+ | self.usages| Boolean | Generate Crossplane Usages for resource dependencies, default False |
204
225
  | self.autoReady | Boolean | Perform auto ready processing on all composed resources, default True |
205
226
 
206
227
  ### Composed Resources
@@ -227,6 +248,7 @@ Resource class:
227
248
  | Resource.connection | Connection | The resource connection details |
228
249
  | Resource.ready | Boolean | The resource ready state |
229
250
  | Resource.unknownsFatal | Boolean | Terminate the composition if this resource has been created and is assigned unknown values, default is Composite.unknownsFatal |
251
+ | Resource.usages | Boolean | Generate Crossplane Usages for this resource, default is Composite.autoReady |
230
252
  | Resource.autoReady | Boolean | Perform auto ready processing on this resource, default is Composite.autoReady |
231
253
 
232
254
  ### Required Resources (AKA Extra Resources)
@@ -366,7 +388,7 @@ spec:
366
388
  ```
367
389
  In one terminal session, run function-pythonic:
368
390
  ```shell
369
- $ function-pythonic --insecure --debug
391
+ $ function-pythonic --insecure --debug --render-unknowns
370
392
  [2025-08-21 15:32:37.966] grpc._cython.cygrpc [DEBUG ] Using AsyncIOEngine.POLLER as I/O engine
371
393
  ```
372
394
  In another terminal session, render the Composite:
@@ -0,0 +1,16 @@
1
+
2
+
3
+ from .composite import BaseComposite
4
+ from .protobuf import append, Map, List, Unknown, Yaml, Json, B64Encode, B64Decode
5
+
6
+ __all__ = [
7
+ 'BaseComposite',
8
+ 'append',
9
+ 'Map',
10
+ 'List',
11
+ 'Unknown',
12
+ 'Yaml',
13
+ 'Json',
14
+ 'B64Encode',
15
+ 'B64Decode',
16
+ ]
@@ -1,5 +1,6 @@
1
1
 
2
2
  import datetime
3
+ from google.protobuf.duration_pb2 import Duration
3
4
  from crossplane.function.proto.v1 import run_function_pb2 as fnv1
4
5
 
5
6
  from . import protobuf
@@ -9,8 +10,18 @@ _notset = object()
9
10
 
10
11
 
11
12
  class BaseComposite:
12
- def __init__(self, request, response, logger):
13
+ def __init__(self, request, logger):
13
14
  self.request = protobuf.Message(None, 'request', request.DESCRIPTOR, request, 'Function Request')
15
+ response = fnv1.RunFunctionResponse(
16
+ meta=fnv1.ResponseMeta(
17
+ tag=request.meta.tag,
18
+ ttl=Duration(
19
+ seconds=60,
20
+ ),
21
+ ),
22
+ desired=request.desired,
23
+ context=request.context,
24
+ )
14
25
  self.response = protobuf.Message(None, 'response', response.DESCRIPTOR, response)
15
26
  self.logger = logger
16
27
  self.credentials = Credentials(self.request)
@@ -20,6 +31,7 @@ class BaseComposite:
20
31
  self.resources = Resources(self)
21
32
  self.unknownsFatal = True
22
33
  self.autoReady = True
34
+ self.usages = False
23
35
 
24
36
  observed = self.request.observed.composite
25
37
  desired = self.response.desired.composite
@@ -36,11 +48,23 @@ class BaseComposite:
36
48
 
37
49
  @property
38
50
  def ttl(self):
39
- return self.response.meta.ttl.seconds
51
+ if self.response.meta.ttl.nanos:
52
+ return float(self.response.meta.ttl.seconds) + (float(self.response.meta.ttl.nanos) / 1000000000.0)
53
+ return int(self.response.meta.ttl.seconds)
40
54
 
41
55
  @ttl.setter
42
56
  def ttl(self, ttl):
43
- self.response.meta.ttl.seconds = ttl
57
+ if isinstance(ttl, int):
58
+ self.response.meta.ttl.seconds = ttl
59
+ self.response.meta.ttl.nanos = 0
60
+ elif isinstance(ttl, float):
61
+ self.response.meta.ttl.seconds = int(ttl)
62
+ if ttl.is_integer():
63
+ self.response.meta.ttl.nanos = 0
64
+ else:
65
+ self.response.meta.ttl.nanos = int((ttl - int(self.response.meta.ttl.seconds)) * 1000000000)
66
+ else:
67
+ raise ValueError('ttl must be an int or float')
44
68
 
45
69
  @property
46
70
  def ready(self):
@@ -55,7 +79,7 @@ class BaseComposite:
55
79
  def ready(self, ready):
56
80
  if ready:
57
81
  ready = fnv1.Ready.READY_TRUE
58
- elif ready == None or (isinstance(ready, protobuf.Values) and ready._isUnknown):
82
+ elif ready == None or (isinstance(ready, protobuf.Value) and ready._isUnknown):
59
83
  ready = fnv1.Ready.READY_UNSPECIFIED
60
84
  else:
61
85
  ready = fnv1.Ready.READY_FALSE
@@ -73,22 +97,46 @@ class Credentials:
73
97
  return self[key]
74
98
 
75
99
  def __getitem__(self, key):
76
- return self._request.credentials[key].credentials_data.data
100
+ return Credential(self._request.credentials[key])
77
101
 
78
102
  def __bool__(self):
79
- return bool(_request.credentials)
103
+ return bool(self._request.credentials)
80
104
 
81
105
  def __len__(self):
82
106
  return len(self._request.credentials)
83
107
 
84
108
  def __contains__(self, key):
85
- return key in _request.credentials
109
+ return key in self._request.credentials
86
110
 
87
111
  def __iter__(self):
88
112
  for key, resource in self._request.credentials:
89
113
  yield key, self[key]
90
114
 
91
115
 
116
+ class Credential:
117
+ def __init__(self, credential):
118
+ self.__dict__['_credential'] = credential
119
+
120
+ def __getattr__(self, key):
121
+ return self[key]
122
+
123
+ def __getitem__(self, key):
124
+ return self._credential.credential_data.data[key]
125
+
126
+ def __bool__(self):
127
+ return bool(self._credential.credential_data.data)
128
+
129
+ def __len__(self):
130
+ return len(self._credential.credential_data.data)
131
+
132
+ def __contains__(self, key):
133
+ return key in self._credential.credential_data.data
134
+
135
+ def __iter__(self):
136
+ for key, resource in self._credential.credential_data.data:
137
+ yield key, self[key]
138
+
139
+
92
140
  class Resources:
93
141
  def __init__(self, composite):
94
142
  self.__dict__['_composite'] = composite
@@ -137,6 +185,7 @@ class Resource:
137
185
  self.connection = Connection(observed)
138
186
  self.unknownsFatal = None
139
187
  self.autoReady = None
188
+ self.usages = None
140
189
 
141
190
  def __call__(self, apiVersion=_notset, kind=_notset, namespace=_notset, name=_notset):
142
191
  self.desired()
@@ -152,7 +201,7 @@ class Resource:
152
201
 
153
202
  @property
154
203
  def apiVersion(self):
155
- return self.observed.apiVersion
204
+ return self.desired.apiVersion
156
205
 
157
206
  @apiVersion.setter
158
207
  def apiVersion(self, apiVersion):
@@ -160,7 +209,7 @@ class Resource:
160
209
 
161
210
  @property
162
211
  def kind(self):
163
- return self.observed.kind
212
+ return self.desired.kind
164
213
 
165
214
  @kind.setter
166
215
  def kind(self, kind):
@@ -218,7 +267,7 @@ class Resource:
218
267
  def ready(self, ready):
219
268
  if ready:
220
269
  ready = fnv1.Ready.READY_TRUE
221
- elif ready == None or (isinstance(ready, protobuf.Values) and ready._isUnknown):
270
+ elif ready == None or (isinstance(ready, protobuf.Value) and ready._isUnknown):
222
271
  ready = fnv1.Ready.READY_UNSPECIFIED
223
272
  else:
224
273
  ready = fnv1.Ready.READY_FALSE
@@ -329,8 +378,8 @@ class RequiredResources:
329
378
  elif isinstance(entry, (list, tuple)):
330
379
  self._selector.match_labels.labels[entry[0]] = entry[1]
331
380
 
332
- def __getitem__(self, key):
333
- return RequiredResource(self.name, self._resources.items[key])
381
+ def __getitem__(self, ix):
382
+ return RequiredResource(self.name, ix, self._resources.items[ix])
334
383
 
335
384
  def __bool__(self):
336
385
  return bool(self._resources.items)
@@ -344,8 +393,9 @@ class RequiredResources:
344
393
 
345
394
 
346
395
  class RequiredResource:
347
- def __init__(self, name, resource):
396
+ def __init__(self, name, ix, resource):
348
397
  self.name = name
398
+ self.ix = ix
349
399
  self.observed = resource.resource
350
400
  self.apiVersion = self.observed.apiVersion
351
401
  self.kind = self.observed.kind
@@ -440,7 +490,7 @@ class Condition(protobuf.ProtobufValue):
440
490
  condition.status = fnv1.Status.STATUS_CONDITION_TRUE
441
491
  elif status == None:
442
492
  condition.status = fnv1.Status.STATUS_CONDITION_UNKNOWN
443
- elif isinstance(status, protobuf.Values) and status._isUnknown:
493
+ elif isinstance(status, protobuf.Value) and status._isUnknown:
444
494
  condition.status = fnv1.Status.STATUS_CONDITION_UNSPECIFIED
445
495
  else:
446
496
  condition.status = fnv1.Status.STATUS_CONDITION_FALSE
@@ -474,7 +524,7 @@ class Condition(protobuf.ProtobufValue):
474
524
  if observed.type == self.type:
475
525
  time = observed.lastTransitionTime
476
526
  if time:
477
- return datetime.datetime.fromisoformat(time)
527
+ return datetime.datetime.fromisoformat(str(time))
478
528
  return None
479
529
 
480
530
  @property
@@ -487,7 +537,7 @@ class Condition(protobuf.ProtobufValue):
487
537
  condition = self._find_condition(True)
488
538
  if claim:
489
539
  condition.target = fnv1.Target.TARGET_COMPOSITE_AND_CLAIM
490
- elif claim == None or (isinstance(claim, protobuf.Values) and claim._isUnknown):
540
+ elif claim == None or (isinstance(claim, protobuf.Value) and claim._isUnknown):
491
541
  condition.target = fnv1.Target.TARGET_UNSPECIFIED
492
542
  else:
493
543
  condition.target = fnv1.Target.TARGET_COMPOSITE
@@ -587,7 +637,7 @@ class Events:
587
637
  def __getitem__(self, key):
588
638
  if key >= len(self._results):
589
639
  return Event()
590
- return Event(self._results[ix])
640
+ return Event(self._results[key])
591
641
 
592
642
  def __iter__(self):
593
643
  for ix in range(len(self._results)):
@@ -664,7 +714,7 @@ class Event:
664
714
  if bool(self):
665
715
  if claim:
666
716
  self._result.target = fnv1.Target.TARGET_COMPOSITE_AND_CLAIM
667
- elif claim == None or (isinstance(claim, protobuf.Values) and claim._isUnknown):
717
+ elif claim == None or (isinstance(claim, protobuf.Value) and claim._isUnknown):
668
718
  self._result.target = fnv1.Target.TARGET_UNSPECIFIED
669
719
  else:
670
720
  self._result.target = fnv1.Target.TARGET_COMPOSITE