mergetbapi 0.0.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.
- __init__.py +0 -0
- google/__init__.py +0 -0
- google/api/__init__.py +255 -0
- grpc/__init__.py +0 -0
- grpc/gateway/__init__.py +0 -0
- grpc/gateway/protoc_gen_openapiv2/__init__.py +0 -0
- grpc/gateway/protoc_gen_openapiv2/options/__init__.py +727 -0
- mergetbapi-0.0.1.dist-info/LICENSE.md +19 -0
- mergetbapi-0.0.1.dist-info/METADATA +24 -0
- mergetbapi-0.0.1.dist-info/RECORD +17 -0
- mergetbapi-0.0.1.dist-info/WHEEL +5 -0
- mergetbapi-0.0.1.dist-info/top_level.txt +7 -0
- portal/__init__.py +0 -0
- portal/v1/__init__.py +6702 -0
- reconcile/__init__.py +314 -0
- validator/__init__.py +104 -0
- xir/__init__.py +1032 -0
reconcile/__init__.py
ADDED
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
2
|
+
# sources: mergetb/tech/reconcile/taskstatus.proto
|
|
3
|
+
# plugin: python-betterproto
|
|
4
|
+
# This file has been @generated
|
|
5
|
+
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
from datetime import (
|
|
8
|
+
datetime,
|
|
9
|
+
timedelta,
|
|
10
|
+
)
|
|
11
|
+
from typing import List
|
|
12
|
+
|
|
13
|
+
import betterproto
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class ReconcilerOp(betterproto.Enum):
|
|
17
|
+
"""
|
|
18
|
+
ReconcilerOp is so we tell the reconciler's main function what we're doing,
|
|
19
|
+
for synchronization.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
Undefined = 0
|
|
23
|
+
Idle = 1
|
|
24
|
+
Init = 2
|
|
25
|
+
Create = 3
|
|
26
|
+
Update = 4
|
|
27
|
+
Delete = 5
|
|
28
|
+
Ensure = 6
|
|
29
|
+
Health = 7
|
|
30
|
+
Pollcheck = 8
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class TaskRecordExistenceTypes(betterproto.Enum):
|
|
34
|
+
"""
|
|
35
|
+
What the task record's existence should be Using multiple of these on the
|
|
36
|
+
same Task/ReconcilerManager/ReconcilerName works for
|
|
37
|
+
Exists/Optional/Deleted, although your TaskForest will be funny. Ignore
|
|
38
|
+
overrides everything else.
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
Exists = 0
|
|
42
|
+
Optional = 1
|
|
43
|
+
Deleted = 2
|
|
44
|
+
Ignore = 3
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class TaskRecordKeyTypes(betterproto.Enum):
|
|
48
|
+
"""Options for how to interpret the key"""
|
|
49
|
+
|
|
50
|
+
SingleKey = 0
|
|
51
|
+
PrefixSpace = 1
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class TaskGoalGoalType(betterproto.Enum):
|
|
55
|
+
"""
|
|
56
|
+
This determines the type of keys in Subkeys, but as subkeys was deprecated,
|
|
57
|
+
the meanings are much simpler now
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
Undefined = 0
|
|
61
|
+
Supergoal = 1
|
|
62
|
+
Supertask = 2
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class TaskStatusStatusType(betterproto.Enum):
|
|
66
|
+
Undefined = 0
|
|
67
|
+
Success = 1
|
|
68
|
+
Deleted = 2
|
|
69
|
+
Pending = 3
|
|
70
|
+
Unresponsive = 4
|
|
71
|
+
Processing = 5
|
|
72
|
+
Error = 6
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class TaskMessageType(betterproto.Enum):
|
|
76
|
+
Undefined = 0
|
|
77
|
+
Error = 1
|
|
78
|
+
Warning = 2
|
|
79
|
+
Info = 3
|
|
80
|
+
Debug = 4
|
|
81
|
+
Trace = 5
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class DeprStatusDeprResultType(betterproto.Enum):
|
|
85
|
+
ResultUndefined = 0
|
|
86
|
+
Working = 1
|
|
87
|
+
Error = 2
|
|
88
|
+
Success = 3
|
|
89
|
+
Stale = 4
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
@dataclass(eq=False, repr=False)
|
|
93
|
+
class TaskRecord(betterproto.Message):
|
|
94
|
+
"""
|
|
95
|
+
small tuple representing indicating a task handled by a specific reconciler
|
|
96
|
+
if Manager or Name is "", then it is considered to be a generic task
|
|
97
|
+
record, meaning that any reconciler can fulfill this record
|
|
98
|
+
"""
|
|
99
|
+
|
|
100
|
+
task: str = betterproto.string_field(1)
|
|
101
|
+
reconciler_manager: str = betterproto.string_field(2)
|
|
102
|
+
reconciler_name: str = betterproto.string_field(3)
|
|
103
|
+
existence: "TaskRecordExistenceTypes" = betterproto.enum_field(4)
|
|
104
|
+
key_type: "TaskRecordKeyTypes" = betterproto.enum_field(5)
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
@dataclass(eq=False, repr=False)
|
|
108
|
+
class TaskGoal(betterproto.Message):
|
|
109
|
+
"""
|
|
110
|
+
TaskGoal Goals are created at the highest level, usually by an apiserver
|
|
111
|
+
handler Reconcilers should never create goals, they should only create
|
|
112
|
+
subtasks
|
|
113
|
+
"""
|
|
114
|
+
|
|
115
|
+
self_key: str = betterproto.string_field(1)
|
|
116
|
+
"""The etcd key used (without the taskgoal prefix)"""
|
|
117
|
+
|
|
118
|
+
name: str = betterproto.string_field(2)
|
|
119
|
+
"""The goal's name, used for display"""
|
|
120
|
+
|
|
121
|
+
desc: str = betterproto.string_field(3)
|
|
122
|
+
"""A description of the goal, used for display"""
|
|
123
|
+
|
|
124
|
+
type: "TaskGoalGoalType" = betterproto.enum_field(4)
|
|
125
|
+
"""The type of goal this is"""
|
|
126
|
+
|
|
127
|
+
self_version: int = betterproto.int64_field(5)
|
|
128
|
+
"""Version of the etcd key, used for the storage interface."""
|
|
129
|
+
|
|
130
|
+
creation: datetime = betterproto.message_field(6)
|
|
131
|
+
"""When the goal was first created."""
|
|
132
|
+
|
|
133
|
+
when: datetime = betterproto.message_field(7)
|
|
134
|
+
"""The last time the goal was written."""
|
|
135
|
+
|
|
136
|
+
subkeys: List[str] = betterproto.string_field(8)
|
|
137
|
+
"""
|
|
138
|
+
The etcd subkeys of the goal. Prefixes to these subkeys are determined by
|
|
139
|
+
the GoalType. deprecated, as we just use Subgoals, Subtasks, and Subrecs
|
|
140
|
+
instead
|
|
141
|
+
"""
|
|
142
|
+
|
|
143
|
+
subgoals: List[str] = betterproto.string_field(9)
|
|
144
|
+
"""Keys of subgoals"""
|
|
145
|
+
|
|
146
|
+
subtasks: List["TaskRecord"] = betterproto.message_field(10)
|
|
147
|
+
"""Keys of subtasks (without the reconciler attached)"""
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
@dataclass(eq=False, repr=False)
|
|
151
|
+
class TaskStatus(betterproto.Message):
|
|
152
|
+
"""
|
|
153
|
+
A TaskStatus is an individual step that changes the state of something to
|
|
154
|
+
accomplish a goal.
|
|
155
|
+
"""
|
|
156
|
+
|
|
157
|
+
reconciler_manager: str = betterproto.string_field(1)
|
|
158
|
+
reconciler_name: str = betterproto.string_field(2)
|
|
159
|
+
desc: str = betterproto.string_field(3)
|
|
160
|
+
last_status: "TaskStatusStatusType" = betterproto.enum_field(4)
|
|
161
|
+
self_version: int = betterproto.int64_field(5)
|
|
162
|
+
"""
|
|
163
|
+
This is the value to set if you want to manually specify the status of a
|
|
164
|
+
Task.
|
|
165
|
+
"""
|
|
166
|
+
|
|
167
|
+
task_version: int = betterproto.int64_field(6)
|
|
168
|
+
prev_value: bytes = betterproto.bytes_field(7)
|
|
169
|
+
duration: timedelta = betterproto.message_field(8)
|
|
170
|
+
"""
|
|
171
|
+
Used to determine if the status is actually up to date and when a key is
|
|
172
|
+
deleted while the reconciler is offline so we know what exactly to
|
|
173
|
+
teardown. When a TaskStatus is used inside of a TaskTree, this is set to
|
|
174
|
+
nil to save data and to not expose these to users.
|
|
175
|
+
"""
|
|
176
|
+
|
|
177
|
+
when: datetime = betterproto.message_field(9)
|
|
178
|
+
task_key: str = betterproto.string_field(10)
|
|
179
|
+
subtask_keys: List[str] = betterproto.string_field(11)
|
|
180
|
+
"""as opposed to a key under which keys are put, i.e. /users/"""
|
|
181
|
+
|
|
182
|
+
messages: List["TaskMessage"] = betterproto.message_field(12)
|
|
183
|
+
current_status: "TaskStatusStatusType" = betterproto.enum_field(13)
|
|
184
|
+
"""Meant for human consumption. "Couldn't create /home/murphy"."""
|
|
185
|
+
|
|
186
|
+
task_revision: int = betterproto.int64_field(14)
|
|
187
|
+
"""
|
|
188
|
+
Because the value of this depends on when the TaskStatus is read, this
|
|
189
|
+
value will be overwritten when the TaskStatus is read. So, if you want to
|
|
190
|
+
manually set the Status of a TaskStatus for use in etcd, DO NOT SET THIS
|
|
191
|
+
VALUE, set LastStatus instead. The value of this depends on: - the version
|
|
192
|
+
and value of the currently written task key - if they don't match, the
|
|
193
|
+
status is "Pending" - if the reconciler doesn't seem to be alive, the
|
|
194
|
+
status is "Unresponsive." - otherwise, this is identical to LastStatus
|
|
195
|
+
"""
|
|
196
|
+
|
|
197
|
+
creation: datetime = betterproto.message_field(15)
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
@dataclass(eq=False, repr=False)
|
|
201
|
+
class TaskMessage(betterproto.Message):
|
|
202
|
+
"""A container for messages with a severity level"""
|
|
203
|
+
|
|
204
|
+
level: "TaskMessageType" = betterproto.enum_field(1)
|
|
205
|
+
message: str = betterproto.string_field(2)
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
@dataclass(eq=False, repr=False)
|
|
209
|
+
class TaskTree(betterproto.Message):
|
|
210
|
+
"""
|
|
211
|
+
TaskTree is the tree of tasks spawned by an etcd key entry. It's a
|
|
212
|
+
collection of task instances and task instances created by those, etc. This
|
|
213
|
+
is ephermeral, i.e. not stored in minio or etcd and sent when requested.
|
|
214
|
+
"""
|
|
215
|
+
|
|
216
|
+
task: "TaskStatus" = betterproto.message_field(1)
|
|
217
|
+
highest_status: "TaskStatusStatusType" = betterproto.enum_field(2)
|
|
218
|
+
last_updated: datetime = betterproto.message_field(3)
|
|
219
|
+
num_child_tasks: int = betterproto.int64_field(4)
|
|
220
|
+
subtasks: List["TaskTree"] = betterproto.message_field(5)
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
@dataclass(eq=False, repr=False)
|
|
224
|
+
class TaskForest(betterproto.Message):
|
|
225
|
+
"""
|
|
226
|
+
Depending on the Goal Type, Task Forest either: - Wraps up all goals
|
|
227
|
+
underneath if it is a supergoal - For example, all subgoals across a
|
|
228
|
+
materialization - Wraps up all tasks underneath if it is a supertask -
|
|
229
|
+
For example, all keys across all reconcilers when /users/murphy is created
|
|
230
|
+
This is ephermeral, i.e. not stored in minio or etcd, and sent when
|
|
231
|
+
requested.
|
|
232
|
+
"""
|
|
233
|
+
|
|
234
|
+
goal: "TaskGoal" = betterproto.message_field(1)
|
|
235
|
+
highest_status: "TaskStatusStatusType" = betterproto.enum_field(2)
|
|
236
|
+
last_updated: datetime = betterproto.message_field(3)
|
|
237
|
+
num_child_tasks: int = betterproto.int64_field(4)
|
|
238
|
+
subgoals: List["TaskForest"] = betterproto.message_field(5)
|
|
239
|
+
subtasks: List["TaskTree"] = betterproto.message_field(6)
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
@dataclass(eq=False, repr=False)
|
|
243
|
+
class TaskSummary(betterproto.Message):
|
|
244
|
+
"""
|
|
245
|
+
This is a summary of a TaskForest Used when we want a status of something,
|
|
246
|
+
but we don't care about the details Usually sent in addition to something,
|
|
247
|
+
like a materialization This is ephermeral, i.e. not stored in minio or
|
|
248
|
+
etcd, and sent when requested.
|
|
249
|
+
"""
|
|
250
|
+
|
|
251
|
+
highest_status: "TaskStatusStatusType" = betterproto.enum_field(1)
|
|
252
|
+
first_updated: datetime = betterproto.message_field(2)
|
|
253
|
+
last_updated: datetime = betterproto.message_field(3)
|
|
254
|
+
messages: List["TaskMessage"] = betterproto.message_field(4)
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
@dataclass(eq=False, repr=False)
|
|
258
|
+
class DeprStatus(betterproto.Message):
|
|
259
|
+
"""
|
|
260
|
+
TODO: Depreciate this. This is currently here for backwards compatibility,
|
|
261
|
+
so we can convert old statuses to new ones.
|
|
262
|
+
"""
|
|
263
|
+
|
|
264
|
+
result: "DeprStatusDeprResultType" = betterproto.enum_field(1)
|
|
265
|
+
"""Status result"""
|
|
266
|
+
|
|
267
|
+
worker: str = betterproto.string_field(2)
|
|
268
|
+
"""The identity of the worker responsible for reporting on this status."""
|
|
269
|
+
|
|
270
|
+
info: str = betterproto.string_field(3)
|
|
271
|
+
"""Typically used for error or warning reporting form the worker."""
|
|
272
|
+
|
|
273
|
+
version: int = betterproto.int64_field(4)
|
|
274
|
+
"""Version of the state key this status is associated with."""
|
|
275
|
+
|
|
276
|
+
reconciler: str = betterproto.string_field(5)
|
|
277
|
+
"""The reconciler who owns this status."""
|
|
278
|
+
|
|
279
|
+
event: str = betterproto.string_field(6)
|
|
280
|
+
"""The event/type of status this is."""
|
|
281
|
+
|
|
282
|
+
when: datetime = betterproto.message_field(7)
|
|
283
|
+
"""When the status was recorded"""
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
@dataclass(eq=False, repr=False)
|
|
287
|
+
class ReconcilerHealth(betterproto.Message):
|
|
288
|
+
"""
|
|
289
|
+
ReconcilerHealth is something that a reconciler periodically checks in on
|
|
290
|
+
and writes values to. This is used to see if a reconciler has gone rogue,
|
|
291
|
+
but also for some basic performance metrics.
|
|
292
|
+
"""
|
|
293
|
+
|
|
294
|
+
manager: str = betterproto.string_field(1)
|
|
295
|
+
name: str = betterproto.string_field(2)
|
|
296
|
+
self_version: int = betterproto.int64_field(3)
|
|
297
|
+
start_time: datetime = betterproto.message_field(4)
|
|
298
|
+
check_in_time: datetime = betterproto.message_field(5)
|
|
299
|
+
duration: timedelta = betterproto.message_field(6)
|
|
300
|
+
unresponsive: bool = betterproto.bool_field(7)
|
|
301
|
+
keys_handled: int = betterproto.int64_field(8)
|
|
302
|
+
last_key: str = betterproto.string_field(9)
|
|
303
|
+
when_last_key: datetime = betterproto.message_field(10)
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
@dataclass(eq=False, repr=False)
|
|
307
|
+
class ServerHeartbeat(betterproto.Message):
|
|
308
|
+
"""
|
|
309
|
+
For reconcilers watching for server heartbeats, the ServerHeartbeat message
|
|
310
|
+
indicates the expected interval between heartbeats
|
|
311
|
+
"""
|
|
312
|
+
|
|
313
|
+
interval: int = betterproto.uint64_field(1)
|
|
314
|
+
when: datetime = betterproto.message_field(2)
|
validator/__init__.py
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
2
|
+
# sources: mwitkow/go-proto-validators/validator.proto
|
|
3
|
+
# plugin: python-betterproto
|
|
4
|
+
# This file has been @generated
|
|
5
|
+
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
|
|
8
|
+
import betterproto
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass(eq=False, repr=False)
|
|
12
|
+
class FieldValidator(betterproto.Message):
|
|
13
|
+
regex: str = betterproto.string_field(1)
|
|
14
|
+
"""Uses a Golang RE2-syntax regex to match the field contents."""
|
|
15
|
+
|
|
16
|
+
int_gt: int = betterproto.int64_field(2)
|
|
17
|
+
"""Field value of integer strictly greater than this value."""
|
|
18
|
+
|
|
19
|
+
int_lt: int = betterproto.int64_field(3)
|
|
20
|
+
"""Field value of integer strictly smaller than this value."""
|
|
21
|
+
|
|
22
|
+
msg_exists: bool = betterproto.bool_field(4)
|
|
23
|
+
"""
|
|
24
|
+
Used for nested message types, requires that the message type exists.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
human_error: str = betterproto.string_field(5)
|
|
28
|
+
"""
|
|
29
|
+
Human error specifies a user-customizable error that is visible to the
|
|
30
|
+
user.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
float_gt: float = betterproto.double_field(6)
|
|
34
|
+
"""
|
|
35
|
+
Field value of double strictly greater than this value. Note that this
|
|
36
|
+
value can only take on a valid floating point value. Use together with
|
|
37
|
+
float_epsilon if you need something more specific.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
float_lt: float = betterproto.double_field(7)
|
|
41
|
+
"""
|
|
42
|
+
Field value of double strictly smaller than this value. Note that this
|
|
43
|
+
value can only take on a valid floating point value. Use together with
|
|
44
|
+
float_epsilon if you need something more specific.
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
float_epsilon: float = betterproto.double_field(8)
|
|
48
|
+
"""
|
|
49
|
+
Field value of double describing the epsilon within which any comparison
|
|
50
|
+
should be considered to be true. For example, when using float_gt = 0.35,
|
|
51
|
+
using a float_epsilon of 0.05 would mean that any value above 0.30 is
|
|
52
|
+
acceptable. It can be thought of as a {float_value_condition} +-
|
|
53
|
+
{float_epsilon}. If unset, no correction for floating point inaccuracies in
|
|
54
|
+
comparisons will be attempted.
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
float_gte: float = betterproto.double_field(9)
|
|
58
|
+
"""
|
|
59
|
+
Floating-point value compared to which the field content should be greater
|
|
60
|
+
or equal.
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
float_lte: float = betterproto.double_field(10)
|
|
64
|
+
"""
|
|
65
|
+
Floating-point value compared to which the field content should be smaller
|
|
66
|
+
or equal.
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
string_not_empty: bool = betterproto.bool_field(11)
|
|
70
|
+
"""
|
|
71
|
+
Used for string fields, requires the string to be not empty (i.e different
|
|
72
|
+
from "").
|
|
73
|
+
"""
|
|
74
|
+
|
|
75
|
+
repeated_count_min: int = betterproto.int64_field(12)
|
|
76
|
+
"""Repeated field with at least this number of elements."""
|
|
77
|
+
|
|
78
|
+
repeated_count_max: int = betterproto.int64_field(13)
|
|
79
|
+
"""Repeated field with at most this number of elements."""
|
|
80
|
+
|
|
81
|
+
length_gt: int = betterproto.int64_field(14)
|
|
82
|
+
"""Field value of length greater than this value."""
|
|
83
|
+
|
|
84
|
+
length_lt: int = betterproto.int64_field(15)
|
|
85
|
+
"""Field value of length smaller than this value."""
|
|
86
|
+
|
|
87
|
+
length_eq: int = betterproto.int64_field(16)
|
|
88
|
+
"""Field value of length strictly equal to this value."""
|
|
89
|
+
|
|
90
|
+
is_in_enum: bool = betterproto.bool_field(17)
|
|
91
|
+
"""Requires that the value is in the enum."""
|
|
92
|
+
|
|
93
|
+
uuid_ver: int = betterproto.int32_field(18)
|
|
94
|
+
"""
|
|
95
|
+
Ensures that a string value is in UUID format. uuid_ver specifies the valid
|
|
96
|
+
UUID versions. Valid values are: 0-5. If uuid_ver is 0 all UUID versions
|
|
97
|
+
are accepted.
|
|
98
|
+
"""
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
@dataclass(eq=False, repr=False)
|
|
102
|
+
class OneofValidator(betterproto.Message):
|
|
103
|
+
required: bool = betterproto.bool_field(1)
|
|
104
|
+
"""Require that one of the oneof fields is set."""
|