crossplane-function-pythonic 0.5.0__py3-none-any.whl → 0.6.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- crossplane/pythonic/__about__.py +1 -1
- crossplane/pythonic/composite.py +157 -3
- crossplane/pythonic/function.py +21 -6
- crossplane/pythonic/grpc.py +26 -4
- crossplane/pythonic/packages.py +128 -96
- crossplane/pythonic/proto/v1/run_function.proto +436 -0
- crossplane/pythonic/proto/v1/run_function_pb2.py +129 -0
- crossplane/pythonic/proto/v1/run_function_pb2.pyi +306 -0
- crossplane/pythonic/proto/v1/run_function_pb2_grpc.py +101 -0
- crossplane/pythonic/protobuf.py +28 -0
- crossplane/pythonic/render.py +107 -10
- {crossplane_function_pythonic-0.5.0.dist-info → crossplane_function_pythonic-0.6.1.dist-info}/METADATA +115 -18
- crossplane_function_pythonic-0.6.1.dist-info/RECORD +22 -0
- crossplane_function_pythonic-0.5.0.dist-info/RECORD +0 -18
- {crossplane_function_pythonic-0.5.0.dist-info → crossplane_function_pythonic-0.6.1.dist-info}/WHEEL +0 -0
- {crossplane_function_pythonic-0.5.0.dist-info → crossplane_function_pythonic-0.6.1.dist-info}/entry_points.txt +0 -0
- {crossplane_function_pythonic-0.5.0.dist-info → crossplane_function_pythonic-0.6.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
import datetime
|
|
2
|
+
|
|
3
|
+
from google.protobuf import duration_pb2 as _duration_pb2
|
|
4
|
+
from google.protobuf import struct_pb2 as _struct_pb2
|
|
5
|
+
from google.protobuf.internal import containers as _containers
|
|
6
|
+
from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper
|
|
7
|
+
from google.protobuf import descriptor as _descriptor
|
|
8
|
+
from google.protobuf import message as _message
|
|
9
|
+
from collections.abc import Iterable as _Iterable, Mapping as _Mapping
|
|
10
|
+
from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union
|
|
11
|
+
|
|
12
|
+
DESCRIPTOR: _descriptor.FileDescriptor
|
|
13
|
+
|
|
14
|
+
class Capability(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
|
15
|
+
__slots__ = ()
|
|
16
|
+
CAPABILITY_UNSPECIFIED: _ClassVar[Capability]
|
|
17
|
+
CAPABILITY_CAPABILITIES: _ClassVar[Capability]
|
|
18
|
+
CAPABILITY_REQUIRED_RESOURCES: _ClassVar[Capability]
|
|
19
|
+
CAPABILITY_CREDENTIALS: _ClassVar[Capability]
|
|
20
|
+
CAPABILITY_CONDITIONS: _ClassVar[Capability]
|
|
21
|
+
CAPABILITY_REQUIRED_SCHEMAS: _ClassVar[Capability]
|
|
22
|
+
|
|
23
|
+
class Ready(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
|
24
|
+
__slots__ = ()
|
|
25
|
+
READY_UNSPECIFIED: _ClassVar[Ready]
|
|
26
|
+
READY_TRUE: _ClassVar[Ready]
|
|
27
|
+
READY_FALSE: _ClassVar[Ready]
|
|
28
|
+
|
|
29
|
+
class Severity(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
|
30
|
+
__slots__ = ()
|
|
31
|
+
SEVERITY_UNSPECIFIED: _ClassVar[Severity]
|
|
32
|
+
SEVERITY_FATAL: _ClassVar[Severity]
|
|
33
|
+
SEVERITY_WARNING: _ClassVar[Severity]
|
|
34
|
+
SEVERITY_NORMAL: _ClassVar[Severity]
|
|
35
|
+
|
|
36
|
+
class Target(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
|
37
|
+
__slots__ = ()
|
|
38
|
+
TARGET_UNSPECIFIED: _ClassVar[Target]
|
|
39
|
+
TARGET_COMPOSITE: _ClassVar[Target]
|
|
40
|
+
TARGET_COMPOSITE_AND_CLAIM: _ClassVar[Target]
|
|
41
|
+
|
|
42
|
+
class Status(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
|
43
|
+
__slots__ = ()
|
|
44
|
+
STATUS_CONDITION_UNSPECIFIED: _ClassVar[Status]
|
|
45
|
+
STATUS_CONDITION_UNKNOWN: _ClassVar[Status]
|
|
46
|
+
STATUS_CONDITION_TRUE: _ClassVar[Status]
|
|
47
|
+
STATUS_CONDITION_FALSE: _ClassVar[Status]
|
|
48
|
+
CAPABILITY_UNSPECIFIED: Capability
|
|
49
|
+
CAPABILITY_CAPABILITIES: Capability
|
|
50
|
+
CAPABILITY_REQUIRED_RESOURCES: Capability
|
|
51
|
+
CAPABILITY_CREDENTIALS: Capability
|
|
52
|
+
CAPABILITY_CONDITIONS: Capability
|
|
53
|
+
CAPABILITY_REQUIRED_SCHEMAS: Capability
|
|
54
|
+
READY_UNSPECIFIED: Ready
|
|
55
|
+
READY_TRUE: Ready
|
|
56
|
+
READY_FALSE: Ready
|
|
57
|
+
SEVERITY_UNSPECIFIED: Severity
|
|
58
|
+
SEVERITY_FATAL: Severity
|
|
59
|
+
SEVERITY_WARNING: Severity
|
|
60
|
+
SEVERITY_NORMAL: Severity
|
|
61
|
+
TARGET_UNSPECIFIED: Target
|
|
62
|
+
TARGET_COMPOSITE: Target
|
|
63
|
+
TARGET_COMPOSITE_AND_CLAIM: Target
|
|
64
|
+
STATUS_CONDITION_UNSPECIFIED: Status
|
|
65
|
+
STATUS_CONDITION_UNKNOWN: Status
|
|
66
|
+
STATUS_CONDITION_TRUE: Status
|
|
67
|
+
STATUS_CONDITION_FALSE: Status
|
|
68
|
+
|
|
69
|
+
class RunFunctionRequest(_message.Message):
|
|
70
|
+
__slots__ = ("meta", "observed", "desired", "input", "context", "extra_resources", "credentials", "required_resources", "required_schemas")
|
|
71
|
+
class ExtraResourcesEntry(_message.Message):
|
|
72
|
+
__slots__ = ("key", "value")
|
|
73
|
+
KEY_FIELD_NUMBER: _ClassVar[int]
|
|
74
|
+
VALUE_FIELD_NUMBER: _ClassVar[int]
|
|
75
|
+
key: str
|
|
76
|
+
value: Resources
|
|
77
|
+
def __init__(self, key: _Optional[str] = ..., value: _Optional[_Union[Resources, _Mapping]] = ...) -> None: ...
|
|
78
|
+
class CredentialsEntry(_message.Message):
|
|
79
|
+
__slots__ = ("key", "value")
|
|
80
|
+
KEY_FIELD_NUMBER: _ClassVar[int]
|
|
81
|
+
VALUE_FIELD_NUMBER: _ClassVar[int]
|
|
82
|
+
key: str
|
|
83
|
+
value: Credentials
|
|
84
|
+
def __init__(self, key: _Optional[str] = ..., value: _Optional[_Union[Credentials, _Mapping]] = ...) -> None: ...
|
|
85
|
+
class RequiredResourcesEntry(_message.Message):
|
|
86
|
+
__slots__ = ("key", "value")
|
|
87
|
+
KEY_FIELD_NUMBER: _ClassVar[int]
|
|
88
|
+
VALUE_FIELD_NUMBER: _ClassVar[int]
|
|
89
|
+
key: str
|
|
90
|
+
value: Resources
|
|
91
|
+
def __init__(self, key: _Optional[str] = ..., value: _Optional[_Union[Resources, _Mapping]] = ...) -> None: ...
|
|
92
|
+
class RequiredSchemasEntry(_message.Message):
|
|
93
|
+
__slots__ = ("key", "value")
|
|
94
|
+
KEY_FIELD_NUMBER: _ClassVar[int]
|
|
95
|
+
VALUE_FIELD_NUMBER: _ClassVar[int]
|
|
96
|
+
key: str
|
|
97
|
+
value: Schema
|
|
98
|
+
def __init__(self, key: _Optional[str] = ..., value: _Optional[_Union[Schema, _Mapping]] = ...) -> None: ...
|
|
99
|
+
META_FIELD_NUMBER: _ClassVar[int]
|
|
100
|
+
OBSERVED_FIELD_NUMBER: _ClassVar[int]
|
|
101
|
+
DESIRED_FIELD_NUMBER: _ClassVar[int]
|
|
102
|
+
INPUT_FIELD_NUMBER: _ClassVar[int]
|
|
103
|
+
CONTEXT_FIELD_NUMBER: _ClassVar[int]
|
|
104
|
+
EXTRA_RESOURCES_FIELD_NUMBER: _ClassVar[int]
|
|
105
|
+
CREDENTIALS_FIELD_NUMBER: _ClassVar[int]
|
|
106
|
+
REQUIRED_RESOURCES_FIELD_NUMBER: _ClassVar[int]
|
|
107
|
+
REQUIRED_SCHEMAS_FIELD_NUMBER: _ClassVar[int]
|
|
108
|
+
meta: RequestMeta
|
|
109
|
+
observed: State
|
|
110
|
+
desired: State
|
|
111
|
+
input: _struct_pb2.Struct
|
|
112
|
+
context: _struct_pb2.Struct
|
|
113
|
+
extra_resources: _containers.MessageMap[str, Resources]
|
|
114
|
+
credentials: _containers.MessageMap[str, Credentials]
|
|
115
|
+
required_resources: _containers.MessageMap[str, Resources]
|
|
116
|
+
required_schemas: _containers.MessageMap[str, Schema]
|
|
117
|
+
def __init__(self, meta: _Optional[_Union[RequestMeta, _Mapping]] = ..., observed: _Optional[_Union[State, _Mapping]] = ..., desired: _Optional[_Union[State, _Mapping]] = ..., input: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ..., context: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ..., extra_resources: _Optional[_Mapping[str, Resources]] = ..., credentials: _Optional[_Mapping[str, Credentials]] = ..., required_resources: _Optional[_Mapping[str, Resources]] = ..., required_schemas: _Optional[_Mapping[str, Schema]] = ...) -> None: ...
|
|
118
|
+
|
|
119
|
+
class Credentials(_message.Message):
|
|
120
|
+
__slots__ = ("credential_data",)
|
|
121
|
+
CREDENTIAL_DATA_FIELD_NUMBER: _ClassVar[int]
|
|
122
|
+
credential_data: CredentialData
|
|
123
|
+
def __init__(self, credential_data: _Optional[_Union[CredentialData, _Mapping]] = ...) -> None: ...
|
|
124
|
+
|
|
125
|
+
class CredentialData(_message.Message):
|
|
126
|
+
__slots__ = ("data",)
|
|
127
|
+
class DataEntry(_message.Message):
|
|
128
|
+
__slots__ = ("key", "value")
|
|
129
|
+
KEY_FIELD_NUMBER: _ClassVar[int]
|
|
130
|
+
VALUE_FIELD_NUMBER: _ClassVar[int]
|
|
131
|
+
key: str
|
|
132
|
+
value: bytes
|
|
133
|
+
def __init__(self, key: _Optional[str] = ..., value: _Optional[bytes] = ...) -> None: ...
|
|
134
|
+
DATA_FIELD_NUMBER: _ClassVar[int]
|
|
135
|
+
data: _containers.ScalarMap[str, bytes]
|
|
136
|
+
def __init__(self, data: _Optional[_Mapping[str, bytes]] = ...) -> None: ...
|
|
137
|
+
|
|
138
|
+
class Resources(_message.Message):
|
|
139
|
+
__slots__ = ("items",)
|
|
140
|
+
ITEMS_FIELD_NUMBER: _ClassVar[int]
|
|
141
|
+
items: _containers.RepeatedCompositeFieldContainer[Resource]
|
|
142
|
+
def __init__(self, items: _Optional[_Iterable[_Union[Resource, _Mapping]]] = ...) -> None: ...
|
|
143
|
+
|
|
144
|
+
class RunFunctionResponse(_message.Message):
|
|
145
|
+
__slots__ = ("meta", "desired", "results", "context", "requirements", "conditions", "output")
|
|
146
|
+
META_FIELD_NUMBER: _ClassVar[int]
|
|
147
|
+
DESIRED_FIELD_NUMBER: _ClassVar[int]
|
|
148
|
+
RESULTS_FIELD_NUMBER: _ClassVar[int]
|
|
149
|
+
CONTEXT_FIELD_NUMBER: _ClassVar[int]
|
|
150
|
+
REQUIREMENTS_FIELD_NUMBER: _ClassVar[int]
|
|
151
|
+
CONDITIONS_FIELD_NUMBER: _ClassVar[int]
|
|
152
|
+
OUTPUT_FIELD_NUMBER: _ClassVar[int]
|
|
153
|
+
meta: ResponseMeta
|
|
154
|
+
desired: State
|
|
155
|
+
results: _containers.RepeatedCompositeFieldContainer[Result]
|
|
156
|
+
context: _struct_pb2.Struct
|
|
157
|
+
requirements: Requirements
|
|
158
|
+
conditions: _containers.RepeatedCompositeFieldContainer[Condition]
|
|
159
|
+
output: _struct_pb2.Struct
|
|
160
|
+
def __init__(self, meta: _Optional[_Union[ResponseMeta, _Mapping]] = ..., desired: _Optional[_Union[State, _Mapping]] = ..., results: _Optional[_Iterable[_Union[Result, _Mapping]]] = ..., context: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ..., requirements: _Optional[_Union[Requirements, _Mapping]] = ..., conditions: _Optional[_Iterable[_Union[Condition, _Mapping]]] = ..., output: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ...) -> None: ...
|
|
161
|
+
|
|
162
|
+
class RequestMeta(_message.Message):
|
|
163
|
+
__slots__ = ("tag", "capabilities")
|
|
164
|
+
TAG_FIELD_NUMBER: _ClassVar[int]
|
|
165
|
+
CAPABILITIES_FIELD_NUMBER: _ClassVar[int]
|
|
166
|
+
tag: str
|
|
167
|
+
capabilities: _containers.RepeatedScalarFieldContainer[Capability]
|
|
168
|
+
def __init__(self, tag: _Optional[str] = ..., capabilities: _Optional[_Iterable[_Union[Capability, str]]] = ...) -> None: ...
|
|
169
|
+
|
|
170
|
+
class Requirements(_message.Message):
|
|
171
|
+
__slots__ = ("extra_resources", "resources", "schemas")
|
|
172
|
+
class ExtraResourcesEntry(_message.Message):
|
|
173
|
+
__slots__ = ("key", "value")
|
|
174
|
+
KEY_FIELD_NUMBER: _ClassVar[int]
|
|
175
|
+
VALUE_FIELD_NUMBER: _ClassVar[int]
|
|
176
|
+
key: str
|
|
177
|
+
value: ResourceSelector
|
|
178
|
+
def __init__(self, key: _Optional[str] = ..., value: _Optional[_Union[ResourceSelector, _Mapping]] = ...) -> None: ...
|
|
179
|
+
class ResourcesEntry(_message.Message):
|
|
180
|
+
__slots__ = ("key", "value")
|
|
181
|
+
KEY_FIELD_NUMBER: _ClassVar[int]
|
|
182
|
+
VALUE_FIELD_NUMBER: _ClassVar[int]
|
|
183
|
+
key: str
|
|
184
|
+
value: ResourceSelector
|
|
185
|
+
def __init__(self, key: _Optional[str] = ..., value: _Optional[_Union[ResourceSelector, _Mapping]] = ...) -> None: ...
|
|
186
|
+
class SchemasEntry(_message.Message):
|
|
187
|
+
__slots__ = ("key", "value")
|
|
188
|
+
KEY_FIELD_NUMBER: _ClassVar[int]
|
|
189
|
+
VALUE_FIELD_NUMBER: _ClassVar[int]
|
|
190
|
+
key: str
|
|
191
|
+
value: SchemaSelector
|
|
192
|
+
def __init__(self, key: _Optional[str] = ..., value: _Optional[_Union[SchemaSelector, _Mapping]] = ...) -> None: ...
|
|
193
|
+
EXTRA_RESOURCES_FIELD_NUMBER: _ClassVar[int]
|
|
194
|
+
RESOURCES_FIELD_NUMBER: _ClassVar[int]
|
|
195
|
+
SCHEMAS_FIELD_NUMBER: _ClassVar[int]
|
|
196
|
+
extra_resources: _containers.MessageMap[str, ResourceSelector]
|
|
197
|
+
resources: _containers.MessageMap[str, ResourceSelector]
|
|
198
|
+
schemas: _containers.MessageMap[str, SchemaSelector]
|
|
199
|
+
def __init__(self, extra_resources: _Optional[_Mapping[str, ResourceSelector]] = ..., resources: _Optional[_Mapping[str, ResourceSelector]] = ..., schemas: _Optional[_Mapping[str, SchemaSelector]] = ...) -> None: ...
|
|
200
|
+
|
|
201
|
+
class SchemaSelector(_message.Message):
|
|
202
|
+
__slots__ = ("api_version", "kind")
|
|
203
|
+
API_VERSION_FIELD_NUMBER: _ClassVar[int]
|
|
204
|
+
KIND_FIELD_NUMBER: _ClassVar[int]
|
|
205
|
+
api_version: str
|
|
206
|
+
kind: str
|
|
207
|
+
def __init__(self, api_version: _Optional[str] = ..., kind: _Optional[str] = ...) -> None: ...
|
|
208
|
+
|
|
209
|
+
class Schema(_message.Message):
|
|
210
|
+
__slots__ = ("openapi_v3",)
|
|
211
|
+
OPENAPI_V3_FIELD_NUMBER: _ClassVar[int]
|
|
212
|
+
openapi_v3: _struct_pb2.Struct
|
|
213
|
+
def __init__(self, openapi_v3: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ...) -> None: ...
|
|
214
|
+
|
|
215
|
+
class ResourceSelector(_message.Message):
|
|
216
|
+
__slots__ = ("api_version", "kind", "match_name", "match_labels", "namespace")
|
|
217
|
+
API_VERSION_FIELD_NUMBER: _ClassVar[int]
|
|
218
|
+
KIND_FIELD_NUMBER: _ClassVar[int]
|
|
219
|
+
MATCH_NAME_FIELD_NUMBER: _ClassVar[int]
|
|
220
|
+
MATCH_LABELS_FIELD_NUMBER: _ClassVar[int]
|
|
221
|
+
NAMESPACE_FIELD_NUMBER: _ClassVar[int]
|
|
222
|
+
api_version: str
|
|
223
|
+
kind: str
|
|
224
|
+
match_name: str
|
|
225
|
+
match_labels: MatchLabels
|
|
226
|
+
namespace: str
|
|
227
|
+
def __init__(self, api_version: _Optional[str] = ..., kind: _Optional[str] = ..., match_name: _Optional[str] = ..., match_labels: _Optional[_Union[MatchLabels, _Mapping]] = ..., namespace: _Optional[str] = ...) -> None: ...
|
|
228
|
+
|
|
229
|
+
class MatchLabels(_message.Message):
|
|
230
|
+
__slots__ = ("labels",)
|
|
231
|
+
class LabelsEntry(_message.Message):
|
|
232
|
+
__slots__ = ("key", "value")
|
|
233
|
+
KEY_FIELD_NUMBER: _ClassVar[int]
|
|
234
|
+
VALUE_FIELD_NUMBER: _ClassVar[int]
|
|
235
|
+
key: str
|
|
236
|
+
value: str
|
|
237
|
+
def __init__(self, key: _Optional[str] = ..., value: _Optional[str] = ...) -> None: ...
|
|
238
|
+
LABELS_FIELD_NUMBER: _ClassVar[int]
|
|
239
|
+
labels: _containers.ScalarMap[str, str]
|
|
240
|
+
def __init__(self, labels: _Optional[_Mapping[str, str]] = ...) -> None: ...
|
|
241
|
+
|
|
242
|
+
class ResponseMeta(_message.Message):
|
|
243
|
+
__slots__ = ("tag", "ttl")
|
|
244
|
+
TAG_FIELD_NUMBER: _ClassVar[int]
|
|
245
|
+
TTL_FIELD_NUMBER: _ClassVar[int]
|
|
246
|
+
tag: str
|
|
247
|
+
ttl: _duration_pb2.Duration
|
|
248
|
+
def __init__(self, tag: _Optional[str] = ..., ttl: _Optional[_Union[datetime.timedelta, _duration_pb2.Duration, _Mapping]] = ...) -> None: ...
|
|
249
|
+
|
|
250
|
+
class State(_message.Message):
|
|
251
|
+
__slots__ = ("composite", "resources")
|
|
252
|
+
class ResourcesEntry(_message.Message):
|
|
253
|
+
__slots__ = ("key", "value")
|
|
254
|
+
KEY_FIELD_NUMBER: _ClassVar[int]
|
|
255
|
+
VALUE_FIELD_NUMBER: _ClassVar[int]
|
|
256
|
+
key: str
|
|
257
|
+
value: Resource
|
|
258
|
+
def __init__(self, key: _Optional[str] = ..., value: _Optional[_Union[Resource, _Mapping]] = ...) -> None: ...
|
|
259
|
+
COMPOSITE_FIELD_NUMBER: _ClassVar[int]
|
|
260
|
+
RESOURCES_FIELD_NUMBER: _ClassVar[int]
|
|
261
|
+
composite: Resource
|
|
262
|
+
resources: _containers.MessageMap[str, Resource]
|
|
263
|
+
def __init__(self, composite: _Optional[_Union[Resource, _Mapping]] = ..., resources: _Optional[_Mapping[str, Resource]] = ...) -> None: ...
|
|
264
|
+
|
|
265
|
+
class Resource(_message.Message):
|
|
266
|
+
__slots__ = ("resource", "connection_details", "ready")
|
|
267
|
+
class ConnectionDetailsEntry(_message.Message):
|
|
268
|
+
__slots__ = ("key", "value")
|
|
269
|
+
KEY_FIELD_NUMBER: _ClassVar[int]
|
|
270
|
+
VALUE_FIELD_NUMBER: _ClassVar[int]
|
|
271
|
+
key: str
|
|
272
|
+
value: bytes
|
|
273
|
+
def __init__(self, key: _Optional[str] = ..., value: _Optional[bytes] = ...) -> None: ...
|
|
274
|
+
RESOURCE_FIELD_NUMBER: _ClassVar[int]
|
|
275
|
+
CONNECTION_DETAILS_FIELD_NUMBER: _ClassVar[int]
|
|
276
|
+
READY_FIELD_NUMBER: _ClassVar[int]
|
|
277
|
+
resource: _struct_pb2.Struct
|
|
278
|
+
connection_details: _containers.ScalarMap[str, bytes]
|
|
279
|
+
ready: Ready
|
|
280
|
+
def __init__(self, resource: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ..., connection_details: _Optional[_Mapping[str, bytes]] = ..., ready: _Optional[_Union[Ready, str]] = ...) -> None: ...
|
|
281
|
+
|
|
282
|
+
class Result(_message.Message):
|
|
283
|
+
__slots__ = ("severity", "message", "reason", "target")
|
|
284
|
+
SEVERITY_FIELD_NUMBER: _ClassVar[int]
|
|
285
|
+
MESSAGE_FIELD_NUMBER: _ClassVar[int]
|
|
286
|
+
REASON_FIELD_NUMBER: _ClassVar[int]
|
|
287
|
+
TARGET_FIELD_NUMBER: _ClassVar[int]
|
|
288
|
+
severity: Severity
|
|
289
|
+
message: str
|
|
290
|
+
reason: str
|
|
291
|
+
target: Target
|
|
292
|
+
def __init__(self, severity: _Optional[_Union[Severity, str]] = ..., message: _Optional[str] = ..., reason: _Optional[str] = ..., target: _Optional[_Union[Target, str]] = ...) -> None: ...
|
|
293
|
+
|
|
294
|
+
class Condition(_message.Message):
|
|
295
|
+
__slots__ = ("type", "status", "reason", "message", "target")
|
|
296
|
+
TYPE_FIELD_NUMBER: _ClassVar[int]
|
|
297
|
+
STATUS_FIELD_NUMBER: _ClassVar[int]
|
|
298
|
+
REASON_FIELD_NUMBER: _ClassVar[int]
|
|
299
|
+
MESSAGE_FIELD_NUMBER: _ClassVar[int]
|
|
300
|
+
TARGET_FIELD_NUMBER: _ClassVar[int]
|
|
301
|
+
type: str
|
|
302
|
+
status: Status
|
|
303
|
+
reason: str
|
|
304
|
+
message: str
|
|
305
|
+
target: Target
|
|
306
|
+
def __init__(self, type: _Optional[str] = ..., status: _Optional[_Union[Status, str]] = ..., reason: _Optional[str] = ..., message: _Optional[str] = ..., target: _Optional[_Union[Target, str]] = ...) -> None: ...
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
|
|
2
|
+
"""Client and server classes corresponding to protobuf-defined services."""
|
|
3
|
+
import grpc
|
|
4
|
+
import warnings
|
|
5
|
+
|
|
6
|
+
from crossplane.pythonic.proto.v1 import run_function_pb2 as crossplane_dot_pythonic_dot_proto_dot_v1_dot_run__function__pb2
|
|
7
|
+
|
|
8
|
+
GRPC_GENERATED_VERSION = '1.80.0'
|
|
9
|
+
GRPC_VERSION = grpc.__version__
|
|
10
|
+
_version_not_supported = False
|
|
11
|
+
|
|
12
|
+
try:
|
|
13
|
+
from grpc._utilities import first_version_is_lower
|
|
14
|
+
_version_not_supported = first_version_is_lower(GRPC_VERSION, GRPC_GENERATED_VERSION)
|
|
15
|
+
except ImportError:
|
|
16
|
+
_version_not_supported = True
|
|
17
|
+
|
|
18
|
+
if _version_not_supported:
|
|
19
|
+
raise RuntimeError(
|
|
20
|
+
f'The grpc package installed is at version {GRPC_VERSION},'
|
|
21
|
+
+ ' but the generated code in crossplane/pythonic/proto/v1/run_function_pb2_grpc.py depends on'
|
|
22
|
+
+ f' grpcio>={GRPC_GENERATED_VERSION}.'
|
|
23
|
+
+ f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}'
|
|
24
|
+
+ f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.'
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class FunctionRunnerServiceStub(object):
|
|
29
|
+
"""A FunctionRunnerService is a function.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
def __init__(self, channel):
|
|
33
|
+
"""Constructor.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
channel: A grpc.Channel.
|
|
37
|
+
"""
|
|
38
|
+
self.RunFunction = channel.unary_unary(
|
|
39
|
+
'/apiextensions.fn.proto.v1.FunctionRunnerService/RunFunction',
|
|
40
|
+
request_serializer=crossplane_dot_pythonic_dot_proto_dot_v1_dot_run__function__pb2.RunFunctionRequest.SerializeToString,
|
|
41
|
+
response_deserializer=crossplane_dot_pythonic_dot_proto_dot_v1_dot_run__function__pb2.RunFunctionResponse.FromString,
|
|
42
|
+
_registered_method=True)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class FunctionRunnerServiceServicer(object):
|
|
46
|
+
"""A FunctionRunnerService is a function.
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
def RunFunction(self, request, context):
|
|
50
|
+
"""RunFunction runs the function.
|
|
51
|
+
"""
|
|
52
|
+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
|
53
|
+
context.set_details('Method not implemented!')
|
|
54
|
+
raise NotImplementedError('Method not implemented!')
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def add_FunctionRunnerServiceServicer_to_server(servicer, server):
|
|
58
|
+
rpc_method_handlers = {
|
|
59
|
+
'RunFunction': grpc.unary_unary_rpc_method_handler(
|
|
60
|
+
servicer.RunFunction,
|
|
61
|
+
request_deserializer=crossplane_dot_pythonic_dot_proto_dot_v1_dot_run__function__pb2.RunFunctionRequest.FromString,
|
|
62
|
+
response_serializer=crossplane_dot_pythonic_dot_proto_dot_v1_dot_run__function__pb2.RunFunctionResponse.SerializeToString,
|
|
63
|
+
),
|
|
64
|
+
}
|
|
65
|
+
generic_handler = grpc.method_handlers_generic_handler(
|
|
66
|
+
'apiextensions.fn.proto.v1.FunctionRunnerService', rpc_method_handlers)
|
|
67
|
+
server.add_generic_rpc_handlers((generic_handler,))
|
|
68
|
+
server.add_registered_method_handlers('apiextensions.fn.proto.v1.FunctionRunnerService', rpc_method_handlers)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
# This class is part of an EXPERIMENTAL API.
|
|
72
|
+
class FunctionRunnerService(object):
|
|
73
|
+
"""A FunctionRunnerService is a function.
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
@staticmethod
|
|
77
|
+
def RunFunction(request,
|
|
78
|
+
target,
|
|
79
|
+
options=(),
|
|
80
|
+
channel_credentials=None,
|
|
81
|
+
call_credentials=None,
|
|
82
|
+
insecure=False,
|
|
83
|
+
compression=None,
|
|
84
|
+
wait_for_ready=None,
|
|
85
|
+
timeout=None,
|
|
86
|
+
metadata=None):
|
|
87
|
+
return grpc.experimental.unary_unary(
|
|
88
|
+
request,
|
|
89
|
+
target,
|
|
90
|
+
'/apiextensions.fn.proto.v1.FunctionRunnerService/RunFunction',
|
|
91
|
+
crossplane_dot_pythonic_dot_proto_dot_v1_dot_run__function__pb2.RunFunctionRequest.SerializeToString,
|
|
92
|
+
crossplane_dot_pythonic_dot_proto_dot_v1_dot_run__function__pb2.RunFunctionResponse.FromString,
|
|
93
|
+
options,
|
|
94
|
+
channel_credentials,
|
|
95
|
+
insecure,
|
|
96
|
+
call_credentials,
|
|
97
|
+
compression,
|
|
98
|
+
wait_for_ready,
|
|
99
|
+
timeout,
|
|
100
|
+
metadata,
|
|
101
|
+
_registered_method=True)
|
crossplane/pythonic/protobuf.py
CHANGED
|
@@ -897,6 +897,32 @@ class Value:
|
|
|
897
897
|
return False
|
|
898
898
|
return False
|
|
899
899
|
|
|
900
|
+
def __or__(self, other):
|
|
901
|
+
kind = self._kind
|
|
902
|
+
if kind not in ('struct_value', 'Struct'):
|
|
903
|
+
return NotImplemented
|
|
904
|
+
if not isinstance(other, (Value, dict)):
|
|
905
|
+
return NotImplemented
|
|
906
|
+
result = Map()
|
|
907
|
+
for key, value in self:
|
|
908
|
+
result[key] = value
|
|
909
|
+
items = other.items() if isinstance(other, dict) else iter(other)
|
|
910
|
+
for key, value in items:
|
|
911
|
+
result[key] = value
|
|
912
|
+
return result
|
|
913
|
+
|
|
914
|
+
def __ror__(self, other):
|
|
915
|
+
if not isinstance(other, dict):
|
|
916
|
+
return NotImplemented
|
|
917
|
+
result = Map()
|
|
918
|
+
for key, value in other.items():
|
|
919
|
+
result[key] = value
|
|
920
|
+
if self._kind not in ('struct_value', 'Struct'):
|
|
921
|
+
return NotImplemented
|
|
922
|
+
for key, value in self:
|
|
923
|
+
result[key] = value
|
|
924
|
+
return result
|
|
925
|
+
|
|
900
926
|
def __str__(self):
|
|
901
927
|
return format(self, '')
|
|
902
928
|
|
|
@@ -986,6 +1012,8 @@ class Value:
|
|
|
986
1012
|
elif len(args):
|
|
987
1013
|
for key in range(len(args)):
|
|
988
1014
|
self[key] = args[key]
|
|
1015
|
+
else:
|
|
1016
|
+
self._ensure_map()
|
|
989
1017
|
return self
|
|
990
1018
|
|
|
991
1019
|
def __setattr__(self, key, value):
|
crossplane/pythonic/render.py
CHANGED
|
@@ -3,19 +3,21 @@ import asyncio
|
|
|
3
3
|
import importlib
|
|
4
4
|
import inflect
|
|
5
5
|
import inspect
|
|
6
|
+
import json
|
|
6
7
|
import kr8s
|
|
7
8
|
import logging
|
|
8
9
|
import pathlib
|
|
9
10
|
import sys
|
|
10
11
|
import yaml
|
|
11
|
-
from crossplane.function.proto.v1 import run_function_pb2 as fnv1
|
|
12
12
|
|
|
13
13
|
from . import (
|
|
14
14
|
command,
|
|
15
|
-
composite,
|
|
16
15
|
function,
|
|
17
16
|
protobuf,
|
|
18
17
|
)
|
|
18
|
+
from .composite import BaseComposite
|
|
19
|
+
from .proto.v1 import run_function_pb2 as fnv1
|
|
20
|
+
|
|
19
21
|
|
|
20
22
|
INFLECT = inflect.engine()
|
|
21
23
|
INFLECT.classical(all=False)
|
|
@@ -58,7 +60,7 @@ class Command(command.Command):
|
|
|
58
60
|
action='append',
|
|
59
61
|
default=[],
|
|
60
62
|
metavar='KEY=VALUE',
|
|
61
|
-
help='Context key-value pairs to pass to the Function pipeline. Values must be
|
|
63
|
+
help='Context key-value pairs to pass to the Function pipeline. Values must be YAML/JSON. Keys take precedence over --context-files.',
|
|
62
64
|
)
|
|
63
65
|
parser.add_argument(
|
|
64
66
|
'--observed-resources', '-o',
|
|
@@ -77,12 +79,12 @@ class Command(command.Command):
|
|
|
77
79
|
help='A YAML file or directory of YAML files specifying required resources to pass to the Function pipeline.',
|
|
78
80
|
)
|
|
79
81
|
parser.add_argument(
|
|
80
|
-
'--
|
|
82
|
+
'--required-schemas', '-s',
|
|
81
83
|
action='append',
|
|
82
84
|
type=pathlib.Path,
|
|
83
85
|
default=[],
|
|
84
86
|
metavar='PATH',
|
|
85
|
-
help='A
|
|
87
|
+
help='A JSON file or directory of JSON files specifying required schemas to pass to the Function pipeline.',
|
|
86
88
|
)
|
|
87
89
|
parser.add_argument(
|
|
88
90
|
'--include-full-xr', '-x',
|
|
@@ -119,11 +121,10 @@ class Command(command.Command):
|
|
|
119
121
|
observed = self.collect_resources(self.args.observed_resources)
|
|
120
122
|
composition = await self.setup_composition(composite, api)
|
|
121
123
|
resources = self.collect_resources(self.args.required_resources)
|
|
122
|
-
|
|
123
|
-
resources.sort(key=lambda resource: str(resource.metadata.name))
|
|
124
|
+
schemas = self.collect_schemas(self.args.required_schemas)
|
|
124
125
|
context = self.setup_context()
|
|
125
126
|
|
|
126
|
-
render = await self.render(composite, observed, composition, resources, context, api, self.args.render_unknowns, self.args.crossplane_v1)
|
|
127
|
+
render = await self.render(composite, observed, composition, resources, schemas, context, api, self.args.render_unknowns, self.args.crossplane_v1)
|
|
127
128
|
if not render:
|
|
128
129
|
sys.exit(1)
|
|
129
130
|
|
|
@@ -212,7 +213,7 @@ class Command(command.Command):
|
|
|
212
213
|
if not inspect.isclass(clazz):
|
|
213
214
|
print(f"Composition class {self.args.composition} is not a class", file=sys.stderr)
|
|
214
215
|
sys.exit(1)
|
|
215
|
-
if not issubclass(clazz,
|
|
216
|
+
if not issubclass(clazz, BaseComposite):
|
|
216
217
|
print(f"Composition class {self.args.composition} is not a subclass of BaseComposite", file=sys.stderr)
|
|
217
218
|
sys.exit(1)
|
|
218
219
|
return self.create_composition(composite, self.args.composition)
|
|
@@ -246,8 +247,25 @@ class Command(command.Command):
|
|
|
246
247
|
else:
|
|
247
248
|
print(f"Specified resource is not a file or a directory: {entry}", file=sys.stderr)
|
|
248
249
|
sys.exit(1)
|
|
250
|
+
resources.sort(key=lambda resource: str(resource.metadata.name))
|
|
249
251
|
return resources
|
|
250
252
|
|
|
253
|
+
def collect_schemas(self, entries):
|
|
254
|
+
schemas = []
|
|
255
|
+
for entry in entries:
|
|
256
|
+
if entry.is_file():
|
|
257
|
+
document = json.loads(entry.read_text())
|
|
258
|
+
schemas.append(protobuf.Value(None, None, document))
|
|
259
|
+
elif entry.is_dir():
|
|
260
|
+
for file in entry.iterdir():
|
|
261
|
+
if file.suffix == '.json':
|
|
262
|
+
document = json.loads(file.read_text())
|
|
263
|
+
schemas.append(protobuf.Value(None, None, document))
|
|
264
|
+
else:
|
|
265
|
+
print(f"Specified resource is not a file or a directory: {entry}", file=sys.stderr)
|
|
266
|
+
sys.exit(1)
|
|
267
|
+
return schemas
|
|
268
|
+
|
|
251
269
|
def setup_context(self):
|
|
252
270
|
# Load the request context with any specified command line options.
|
|
253
271
|
context = protobuf.Map()
|
|
@@ -269,7 +287,7 @@ class Command(command.Command):
|
|
|
269
287
|
context[key_value[0]] = protobuf.Yaml(key_value[1])
|
|
270
288
|
return context
|
|
271
289
|
|
|
272
|
-
async def render(self, composite, observed=[], composition=None, resources=[], context=None, api=None, render_unknowns=False, crossplane_v1=False, composite_observeds=True):
|
|
290
|
+
async def render(self, composite, observed=[], composition=None, resources=[], schemas=[], context=None, api=None, render_unknowns=False, crossplane_v1=False, composite_observeds=True):
|
|
273
291
|
# Create the request used when running Composition steps.
|
|
274
292
|
request = protobuf.Message(None, 'request', fnv1.RunFunctionRequest.DESCRIPTOR, fnv1.RunFunctionRequest())
|
|
275
293
|
if context is not None:
|
|
@@ -362,6 +380,10 @@ class Command(command.Command):
|
|
|
362
380
|
request.extra_resources()
|
|
363
381
|
for name, selector in requirements.extra_resources:
|
|
364
382
|
await self.set_required(name, selector, request.extra_resources, resources, api)
|
|
383
|
+
# Fetch the schemas requested.
|
|
384
|
+
request.required_schemas()
|
|
385
|
+
for name, selector in requirements.schemas:
|
|
386
|
+
await self.set_schema(name, selector, request.required_schemas, schemas, api)
|
|
365
387
|
# Run the step using the function-pythonic function runner.
|
|
366
388
|
response = protobuf.Message(
|
|
367
389
|
None,
|
|
@@ -546,6 +568,81 @@ class Command(command.Command):
|
|
|
546
568
|
for key, value in connection.data:
|
|
547
569
|
destination.connection_details[key] = protobuf.B64Decode(value)
|
|
548
570
|
|
|
571
|
+
async def set_schema(self, name, selector, schemas, documents=[], api=None):
|
|
572
|
+
if not name:
|
|
573
|
+
return
|
|
574
|
+
name = str(name)
|
|
575
|
+
schema = schemas[name].openapi_v3
|
|
576
|
+
schema() # Force this to get created
|
|
577
|
+
gvk = protobuf.Map(kind=selector.kind)
|
|
578
|
+
version = str(selector.api_version)
|
|
579
|
+
if '/' in version:
|
|
580
|
+
gvk.group, gvk.version = version.split('/', 1)
|
|
581
|
+
else:
|
|
582
|
+
gvk.group = ''
|
|
583
|
+
gvk.version = version
|
|
584
|
+
for document in documents:
|
|
585
|
+
if self.find_schema(gvk, document, schema):
|
|
586
|
+
return
|
|
587
|
+
if api:
|
|
588
|
+
if gvk.group == '':
|
|
589
|
+
url = f"api/{gvk.version}"
|
|
590
|
+
else:
|
|
591
|
+
url = f"apis/{gvk.group}/{gvk.version}"
|
|
592
|
+
try:
|
|
593
|
+
async with api.call_api(base='/openapi/v3', version='', url=url) as response:
|
|
594
|
+
document = protobuf.Value(None, None, response.json())
|
|
595
|
+
except kr8s.NotFoundError:
|
|
596
|
+
return
|
|
597
|
+
self.find_schema(gvk, document, schema)
|
|
598
|
+
|
|
599
|
+
def find_schema(self, gvk, document, schema):
|
|
600
|
+
for name, s in document.components.schemas:
|
|
601
|
+
gvks = s['x-kubernetes-group-version-kind']
|
|
602
|
+
if len(gvks) == 1 and gvks[0] == gvk:
|
|
603
|
+
self.resolve_ref(document, set(), f"#/components/schemas/{name}", schema)
|
|
604
|
+
return True
|
|
605
|
+
return False
|
|
606
|
+
|
|
607
|
+
def resolve_ref(self, document, visiting, ref, schema):
|
|
608
|
+
if not ref:
|
|
609
|
+
return
|
|
610
|
+
ref = str(ref)
|
|
611
|
+
if ref in visiting:
|
|
612
|
+
return
|
|
613
|
+
d = None
|
|
614
|
+
for segment in ref.split('/'):
|
|
615
|
+
if segment == '#':
|
|
616
|
+
d = document
|
|
617
|
+
else:
|
|
618
|
+
d = d[segment]
|
|
619
|
+
if not d:
|
|
620
|
+
return
|
|
621
|
+
visiting.add(ref)
|
|
622
|
+
try:
|
|
623
|
+
for name, value in d:
|
|
624
|
+
self.copy_schema(document, visiting, name, value, schema)
|
|
625
|
+
finally:
|
|
626
|
+
visiting.remove(ref)
|
|
627
|
+
|
|
628
|
+
def copy_schema(self, document, visiting, key, value, schema):
|
|
629
|
+
if key == '$ref':
|
|
630
|
+
self.resolve_ref(document, visiting, value, schema)
|
|
631
|
+
elif key == 'allOf':
|
|
632
|
+
if value._isList and len(value) == 1:
|
|
633
|
+
self.resolve_ref(document, visiting, value[0]['$ref'], schema)
|
|
634
|
+
else:
|
|
635
|
+
if value._isMap:
|
|
636
|
+
s = schema[key]
|
|
637
|
+
for n, v in value:
|
|
638
|
+
self.copy_schema(document, visiting, n, v, s)
|
|
639
|
+
elif value._isList:
|
|
640
|
+
s = schema[key]
|
|
641
|
+
for ix, v in enumerate(value):
|
|
642
|
+
self.copy_schema(document, visiting, ix, v, s)
|
|
643
|
+
else:
|
|
644
|
+
schema[key] = value
|
|
645
|
+
|
|
549
646
|
def copy_resource(self, source, destination):
|
|
550
647
|
destination.resource = source.resource
|
|
551
648
|
destination.connection_details()
|