crossplane-function-pythonic 0.6.1__py3-none-any.whl → 0.6.3__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.
@@ -1,2 +1,8 @@
1
- # This is set at build time, using "hatch version"
2
- __version__ = "0.6.1"
1
+ from importlib.metadata import PackageNotFoundError, version
2
+
3
+ try:
4
+ __version__ = version(
5
+ "crossplane-function-pythonic"
6
+ ) # Use the exact [project.name] from pyproject.toml
7
+ except PackageNotFoundError:
8
+ __version__ = "0.0.0"
@@ -1,17 +1,25 @@
1
-
2
-
3
1
  from .composite import BaseComposite
4
- from .protobuf import append, Map, List, Unknown, Yaml, YamlAll, Json, B64Encode, B64Decode
2
+ from .protobuf import (
3
+ B64Decode,
4
+ B64Encode,
5
+ Json,
6
+ List,
7
+ Map,
8
+ Unknown,
9
+ Yaml,
10
+ YamlAll,
11
+ append,
12
+ )
5
13
 
6
14
  __all__ = [
7
- 'BaseComposite',
8
- 'append',
9
- 'Map',
10
- 'List',
11
- 'Unknown',
12
- 'Yaml',
13
- 'YamlAll',
14
- 'Json',
15
- 'B64Encode',
16
- 'B64Decode',
15
+ "B64Decode",
16
+ "B64Encode",
17
+ "BaseComposite",
18
+ "Json",
19
+ "List",
20
+ "Map",
21
+ "Unknown",
22
+ "Yaml",
23
+ "YamlAll",
24
+ "append",
17
25
  ]
@@ -1,2 +1,3 @@
1
1
  from . import main
2
+
2
3
  main.main()
@@ -1,8 +1,9 @@
1
-
2
1
  def resource_ready(resource):
3
2
  if not resource.observed:
4
3
  return None
5
- return _checks.get((resource.observed.apiVersion, resource.observed.kind), _check_default).ready(resource)
4
+ return _checks.get(
5
+ (resource.observed.apiVersion, resource.observed.kind), _check_default
6
+ ).ready(resource)
6
7
 
7
8
 
8
9
  class ReadyCondition:
@@ -16,35 +17,42 @@ class ReadyCondition:
16
17
  return resource.status.notReadyCondition[ready.reason]
17
18
  return resource.status.notReadyCondition
18
19
 
20
+
19
21
  _checks = {}
20
22
  _check_default = ReadyCondition()
21
23
 
24
+
22
25
  class Check:
23
26
  @classmethod
24
27
  def __init_subclass__(cls, **kwargs):
25
28
  super().__init_subclass__(**kwargs)
26
- if hasattr(cls, 'apiVersion'):
29
+ if hasattr(cls, "apiVersion"):
27
30
  _checks[(cls.apiVersion, cls.__name__)] = cls()
28
31
 
29
32
  def ready(self, resource):
30
33
  raise NotImplementedError()
31
34
 
35
+
32
36
  class AlwaysReady(Check):
33
37
  def ready(self, resource):
34
38
  return resource.observed.metadata.name
35
39
 
36
40
 
37
41
  class ClusterRole(AlwaysReady):
38
- apiVersion = 'rbac.authorization.k8s.io/v1'
42
+ apiVersion = "rbac.authorization.k8s.io/v1"
43
+
39
44
 
40
45
  class ClusterRoleBinding(AlwaysReady):
41
- apiVersion = 'rbac.authorization.k8s.io/v1'
46
+ apiVersion = "rbac.authorization.k8s.io/v1"
47
+
42
48
 
43
49
  class ConfigMap(AlwaysReady):
44
- apiVersion = 'v1'
50
+ apiVersion = "v1"
51
+
45
52
 
46
53
  class CronJob(Check):
47
- apiVersion = 'batch/v1'
54
+ apiVersion = "batch/v1"
55
+
48
56
  def ready(self, resource):
49
57
  if resource.observed.spec.suspend and len(resource.observed.spec.suspend):
50
58
  return resource.observed.metadata.name
@@ -54,17 +62,21 @@ class CronJob(Check):
54
62
  return resource.observed.metadata.name
55
63
  if not resource.status.lastSuccessfulTime:
56
64
  return resource.status.lastSuccessfulTime
57
- if str(resource.status.lastSuccessfulTime) < str(resource.status.lastScheduleTime):
65
+ if str(resource.status.lastSuccessfulTime) < str(
66
+ resource.status.lastScheduleTime
67
+ ):
58
68
  return resource.status.successfulBeforeSchedule
59
69
  return resource.observed.metadata.name
60
70
 
71
+
61
72
  class DaemonSet(Check):
62
- apiVersion = 'apps/v1'
73
+ apiVersion = "apps/v1"
74
+
63
75
  def ready(self, resource):
64
76
  scheduled = resource.status.desiredNumberScheduled
65
77
  if not scheduled:
66
78
  return scheduled
67
- for field in ('numberReady', 'updatedNumberScheduled', 'numberAvailable'):
79
+ for field in ("numberReady", "updatedNumberScheduled", "numberAvailable"):
68
80
  value = resource.status[field]
69
81
  if not value:
70
82
  return value
@@ -72,16 +84,18 @@ class DaemonSet(Check):
72
84
  return resource.status[f"{field}NotScheduled"]
73
85
  return resource.observed.metadata.name
74
86
 
87
+
75
88
  class Deployment(Check):
76
- apiVersion = 'apps/v1'
89
+ apiVersion = "apps/v1"
90
+
77
91
  def ready(self, resource):
78
92
  replicas = resource.observed.spec.replicas or 1
79
- for field in ('updatedReplicas', 'availableReplicas'):
93
+ for field in ("updatedReplicas", "availableReplicas"):
80
94
  value = resource.status[field]
81
95
  if not value:
82
96
  return value
83
97
  if replicas != value:
84
- return resource.status[F"{field}NotReplicas"]
98
+ return resource.status[f"{field}NotReplicas"]
85
99
  available = resource.conditions.Available
86
100
  if not available:
87
101
  return resource.status.notAvailable
@@ -91,28 +105,39 @@ class Deployment(Check):
91
105
  return resource.status.notAvailable
92
106
  return resource.observed.metadata.name
93
107
 
108
+
94
109
  class HorizontalPodAutoscaler(Check):
95
- apiVersion = 'autoscaling/v2'
110
+ apiVersion = "autoscaling/v2"
111
+
96
112
  def ready(self, resource):
97
- for type in ('FailedGetScale', 'FailedUpdateScale', 'FailedGetResourceMetric', 'InvalidSelector'):
113
+ for type in (
114
+ "FailedGetScale",
115
+ "FailedUpdateScale",
116
+ "FailedGetResourceMetric",
117
+ "InvalidSelector",
118
+ ):
98
119
  if resource.conditions[type].status:
99
120
  return resource.status[f"is{type}"]
100
- for type in ('ScalingActive', 'ScalingLimited'):
121
+ for type in ("ScalingActive", "ScalingLimited"):
101
122
  if resource.conditions[type].status:
102
123
  return resource.observed.metadata.name
103
124
  return resource.status.notScalingActiveOrLimiited
104
125
 
126
+
105
127
  class Ingress(Check):
106
- apiVersion = 'networking.k8s.io/v1'
128
+ apiVersion = "networking.k8s.io/v1"
129
+
107
130
  def ready(self, resource):
108
131
  if not len(resource.status.loadBalancer.ingress):
109
132
  return resource.status.noLoadBalanceIngresses
110
133
  return resource.observed.metadata.name
111
134
 
135
+
112
136
  class Job(Check):
113
- apiVersion = 'batch/v1'
137
+ apiVersion = "batch/v1"
138
+
114
139
  def ready(self, resource):
115
- for type in ('Failed', 'Suspended'):
140
+ for type in ("Failed", "Suspended"):
116
141
  if resource.conditions[type].status:
117
142
  return resource.status[f"is{type}"]
118
143
  complete = resource.conditions.Complete
@@ -124,71 +149,94 @@ class Job(Check):
124
149
  return resource.status.notComplete
125
150
  return resource.observed.metadata.name
126
151
 
152
+
127
153
  class Namespace(AlwaysReady):
128
- apiVersion = 'v1'
154
+ apiVersion = "v1"
155
+
129
156
 
130
157
  class PersistentVolumeClaim(Check):
131
- apiVersion = 'v1'
158
+ apiVersion = "v1"
159
+
132
160
  def ready(self, resource):
133
- if resource.status.phase != 'Bound':
161
+ if resource.status.phase != "Bound":
134
162
  return resource.status.phaseNotBound
135
163
  return resource.observed.metadata.name
136
164
 
165
+
137
166
  class Pod(Check):
138
- apiVersion = 'v1'
167
+ apiVersion = "v1"
168
+
139
169
  def ready(self, resource):
140
- if resource.status.phase == 'Succeeded':
170
+ if resource.status.phase == "Succeeded":
171
+ return resource.observed.metadata.name
172
+ if (
173
+ resource.status.phase == "Running"
174
+ and resource.observed.spec.restartPolicy == "Always"
175
+ and resource.conditions.Ready.status
176
+ ):
141
177
  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
178
  return resource.status.notSucceededOrRunning
147
179
 
180
+
148
181
  class ReplicaSet(Check):
149
- apiVersion = 'v1'
182
+ apiVersion = "v1"
183
+
150
184
  def ready(self, resource):
151
- if int(resource.status.observedGeneration) < int(resource.observed.metadata.generation):
185
+ if int(resource.status.observedGeneration) < int(
186
+ resource.observed.metadata.generation
187
+ ):
152
188
  return resource.status.priorObservedGeneration
153
189
  if resource.conditions.ReplicaFailure.status:
154
190
  if resource.conditions.ReplicaFailure.reason:
155
- return resource.status.isReplicaFailure[resource.conditions.ReplicaFailure.reason]
191
+ return resource.status.isReplicaFailure[
192
+ resource.conditions.ReplicaFailure.reason
193
+ ]
156
194
  return resource.status.isReplicaFailure
157
- if int(resource.status.availableReplicas) < int(resource.observed.spec.replicas or 1):
195
+ if int(resource.status.availableReplicas) < int(
196
+ resource.observed.spec.replicas or 1
197
+ ):
158
198
  return resource.status.tooFewavailableReplicas
159
199
  return resource.observed.metadata.name
160
200
 
201
+
161
202
  class Role(AlwaysReady):
162
- apiVersion = 'rbac.authorization.k8s.io/v1'
203
+ apiVersion = "rbac.authorization.k8s.io/v1"
204
+
163
205
 
164
206
  class RoleBinding(AlwaysReady):
165
- apiVersion = 'rbac.authorization.k8s.io/v1'
207
+ apiVersion = "rbac.authorization.k8s.io/v1"
208
+
166
209
 
167
210
  class Secret(AlwaysReady):
168
- apiVersion = 'v1'
211
+ apiVersion = "v1"
212
+
169
213
 
170
214
  class Service(Check):
171
- apiVersion = 'v1'
215
+ apiVersion = "v1"
216
+
172
217
  def ready(self, resource):
173
- if resource.observed.spec.type != 'LoadBalancer':
218
+ if resource.observed.spec.type != "LoadBalancer":
174
219
  return resource.observed.metadata.name
175
220
  if not len(resource.status.loadBalancer.ingress):
176
221
  return resource.status.noLoadBalancerIngresses
177
222
  return resource.observed.metadata.name
178
223
 
224
+
179
225
  class ServiceAccount(AlwaysReady):
180
- apiVersion = 'v1'
226
+ apiVersion = "v1"
227
+
181
228
 
182
229
  class StatefulSet(Check):
183
- apiVersion = 'apps/v1'
230
+ apiVersion = "apps/v1"
231
+
184
232
  def ready(self, resource):
185
233
  replicas = resource.observed.spec.replicas or 1
186
- for field in ('readyReplicas', 'currentReplicas'):
234
+ for field in ("readyReplicas", "currentReplicas"):
187
235
  value = resource.status[field]
188
236
  if not value:
189
237
  return value
190
238
  if replicas != value:
191
- return resource.status[F"{field}NotReplicas"]
239
+ return resource.status[f"{field}NotReplicas"]
192
240
  if resource.status.currentRevision != resource.status.updateRevision:
193
241
  return resource.status.currentRevisionNotUpdateReivsion
194
242
  return resource.observed.metadata.name
@@ -1,4 +1,3 @@
1
-
2
1
  import logging
3
2
  import pathlib
4
3
  import sys
@@ -11,7 +10,9 @@ class Command:
11
10
 
12
11
  @classmethod
13
12
  def create(cls, subparsers):
14
- parser = subparsers.add_parser(cls.name, help=cls.help, description=cls.description)
13
+ parser = subparsers.add_parser(
14
+ cls.name, help=cls.help, description=cls.description
15
+ )
15
16
  parser.set_defaults(command=cls)
16
17
  cls.add_parser_arguments(parser)
17
18
 
@@ -22,45 +23,47 @@ class Command:
22
23
  @classmethod
23
24
  def add_function_arguments(cls, parser):
24
25
  parser.add_argument(
25
- '--debug', '-d',
26
- action='store_true',
27
- help='Emit debug logs.',
26
+ "--debug",
27
+ "-d",
28
+ action="store_true",
29
+ help="Emit debug logs.",
28
30
  )
29
31
  parser.add_argument(
30
- '--log-name-width',
32
+ "--log-name-width",
31
33
  type=int,
32
34
  default=40,
33
- metavar='WIDTH',
34
- help='Width of the logger name in the log output, default 40.',
35
+ metavar="WIDTH",
36
+ help="Width of the logger name in the log output, default 40.",
35
37
  )
36
38
  parser.add_argument(
37
- '--logger-level',
38
- action='append',
39
+ "--logger-level",
40
+ action="append",
39
41
  default=[],
40
- metavar='LOGGER=LEVEL',
41
- help='Logger level, for example: botocore.hooks=INFO',
42
+ metavar="LOGGER=LEVEL",
43
+ help="Logger level, for example: botocore.hooks=INFO",
42
44
  )
43
45
  parser.add_argument(
44
- '--python-path',
45
- action='append',
46
+ "--python-path",
47
+ action="append",
46
48
  default=[],
47
- metavar='DIRECTORY',
48
- help='Filing system directories to add to the python path.',
49
+ metavar="DIRECTORY",
50
+ help="Filing system directories to add to the python path.",
49
51
  )
50
52
  parser.add_argument(
51
- '--render-unknowns', '-u',
52
- action='store_true',
53
- help='Render resources with unknowns, useful during local development.'
53
+ "--render-unknowns",
54
+ "-u",
55
+ action="store_true",
56
+ help="Render resources with unknowns, useful during local development.",
54
57
  )
55
58
  parser.add_argument(
56
- '--allow-oversize-protos',
57
- action='store_true',
58
- help='Allow oversized protobuf messages',
59
+ "--allow-oversize-protos",
60
+ action="store_true",
61
+ help="Allow oversized protobuf messages",
59
62
  )
60
63
  parser.add_argument(
61
- '--crossplane-v1',
62
- action='store_true',
63
- help='Enable Crossplane V1 compatibility mode',
64
+ "--crossplane-v1",
65
+ action="store_true",
66
+ help="Enable Crossplane V1 compatibility mode",
64
67
  )
65
68
 
66
69
  def __init__(self, args=None):
@@ -78,14 +81,14 @@ class Command:
78
81
  logger.handlers = [handler]
79
82
  logger.setLevel(logging.DEBUG if self.args.debug else logging.INFO)
80
83
  # Suppress noisy libraries, these can be overriden using --logger-level
81
- logging.getLogger('asyncio').setLevel(logging.INFO)
82
- logging.getLogger('grpc').setLevel(logging.INFO)
83
- logging.getLogger('httpcore').setLevel(logging.INFO)
84
- logging.getLogger('httpx').setLevel(logging.WARNING)
85
- logging.getLogger('kr8s').setLevel(logging.INFO)
86
- for logger_level in self.args.logger_level:
87
- for logger_level in logger_level.split(','):
88
- logger_level = logger_level.split('=')
84
+ logging.getLogger("asyncio").setLevel(logging.INFO)
85
+ logging.getLogger("grpc").setLevel(logging.INFO)
86
+ logging.getLogger("httpcore").setLevel(logging.INFO)
87
+ logging.getLogger("httpx").setLevel(logging.WARNING)
88
+ logging.getLogger("kr8s").setLevel(logging.INFO)
89
+ for logger_levels in self.args.logger_level:
90
+ for logger_level in logger_levels.split(","):
91
+ logger_level = logger_level.split("=")
89
92
  if len(logger_level) == 2:
90
93
  logging.getLogger(logger_level[0]).setLevel(logger_level[1].upper())
91
94
 
@@ -94,6 +97,7 @@ class Command:
94
97
 
95
98
  if self.args.allow_oversize_protos:
96
99
  from google.protobuf.internal import api_implementation
100
+
97
101
  if api_implementation._c_module:
98
102
  api_implementation._c_module.SetAllowOversizeProtos(True)
99
103
 
@@ -103,10 +107,10 @@ class Command:
103
107
 
104
108
  class Formatter(logging.Formatter):
105
109
  def __init__(self, name_width):
106
- super(Formatter, self).__init__(
110
+ super().__init__(
107
111
  f"[{{asctime}}.{{msecs:03.0f}}] {{sname:{name_width}.{name_width}}} [{{levelname:8.8}}] {{message}}",
108
- '%Y-%m-%d %H:%M:%S',
109
- '{',
112
+ "%Y-%m-%d %H:%M:%S",
113
+ "{",
110
114
  )
111
115
  self.name_width = name_width
112
116
 
@@ -114,12 +118,12 @@ class Formatter(logging.Formatter):
114
118
  record.sname = record.name
115
119
  extra = len(record.sname) - self.name_width
116
120
  if extra > 0:
117
- names = record.sname.split('.')
121
+ names = record.sname.split(".")
118
122
  for ix, name in enumerate(names):
119
123
  if len(name) > extra:
120
124
  names[ix] = name[extra:]
121
125
  break
122
126
  names[ix] = name[:1]
123
127
  extra -= len(name) - 1
124
- record.sname = '.'.join(names)
125
- return super(Formatter, self).format(record)
128
+ record.sname = ".".join(names)
129
+ return super().format(record)