forked from RedHatQE/openshift-python-wrapper
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvalidation_troubleshooting.py
More file actions
309 lines (260 loc) · 9.16 KB
/
validation_troubleshooting.py
File metadata and controls
309 lines (260 loc) · 9.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
#!/usr/bin/env python
"""
OpenShift Python Wrapper - Validation Troubleshooting Guide
This script demonstrates common validation errors and how to fix them.
Run this script to see examples of validation errors and their solutions.
"""
from ocp_resources.deployment import Deployment
from ocp_resources.exceptions import ValidationError
from ocp_resources.pod import Pod
from ocp_resources.service import Service
def print_error_case(title, description):
"""Print an error case header"""
print(f"\n{'─' * 60}")
print(f"❌ {title}")
print(f" {description}")
print(f"{'─' * 60}\n")
def print_solution(solution):
"""Print the solution"""
print(f"\n✅ Solution: {solution}\n")
def case_1_missing_required_fields():
"""Case 1: Missing required fields"""
print_error_case(
title="Missing Required Fields", description="One of the most common errors - forgetting required fields"
)
# Problem: Missing image in container
print("Problem code:")
print("""
pod = Pod(
name="my-pod",
namespace="default",
containers=[{"name": "nginx"}] # Missing 'image'
)
""")
try:
pod = Pod(name="my-pod", namespace="default", containers=[{"name": "nginx"}])
pod.validate()
except ValidationError as e:
print(f"Error: {e}")
print_solution(solution="Add all required fields according to the Kubernetes API spec")
print("Fixed code:")
print("""
pod = Pod(
name="my-pod",
namespace="default",
containers=[{
"name": "nginx",
"image": "nginx:latest" # Added required field
}]
)
""")
def case_2_wrong_types():
"""Case 2: Wrong data types"""
print_error_case(
title="Wrong Data Types", description="Using incorrect types for fields (string instead of int, etc.)"
)
# Problem: replicas should be integer
print("Problem code:")
print("""
deployment_dict = {
"spec": {
"replicas": "3" # Should be integer, not string
}
}
""")
deployment_dict = {
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {"name": "my-deployment"},
"spec": {
"replicas": "3", # Wrong type
"selector": {"matchLabels": {"app": "nginx"}},
"template": {
"metadata": {"labels": {"app": "nginx"}},
"spec": {"containers": [{"name": "nginx", "image": "nginx:latest"}]},
},
},
}
try:
Deployment.validate_dict(resource_dict=deployment_dict)
except ValidationError as e:
print(f"Error: {e}")
print_solution(solution="Use the correct data type (integer for replicas)")
print("Fixed code:")
print("""
deployment_dict = {
"spec": {
"replicas": 3 # Correct integer type
}
}
""")
def case_3_invalid_field_values():
"""Case 3: Invalid field values"""
print_error_case(
title="Invalid Field Values", description="Using values that don't match the allowed pattern or range"
)
# Problem: Invalid DNS name
print("Problem code:")
print("""
pod = Pod(
name="My-Pod-123", # Capital letters not allowed
namespace="default"
)
""")
try:
pod = Pod(
name="My-Pod-123", # Invalid DNS name
namespace="default",
containers=[{"name": "nginx", "image": "nginx:latest"}],
)
pod.validate()
except ValidationError as e:
print(f"Error: {e}")
print_solution(solution="Follow Kubernetes naming conventions (lowercase, alphanumeric, hyphens)")
print("Fixed code:")
print("""
pod = Pod(
name="my-pod-123", # Valid DNS name
namespace="default"
)
""")
def case_4_invalid_structure():
"""Case 4: Invalid resource structure"""
print_error_case(
title="Invalid Resource Structure", description="Incorrect nesting or structure of resource fields"
)
# Problem: ports should be an array
print("Problem code:")
print("""
service = Service(
name="my-service",
namespace="default",
selector={"app": "nginx"},
ports={"port": 80} # Should be array, not dict
)
""")
try:
# This will fail during object creation, not validation
service_dict = {
"apiVersion": "v1",
"kind": "Service",
"metadata": {"name": "my-service", "namespace": "default"},
"spec": {
"selector": {"app": "nginx"},
"ports": {"port": 80}, # Wrong structure
},
}
Service.validate_dict(resource_dict=service_dict)
except ValidationError as e:
print(f"Error: {e}")
print_solution(solution="Use correct structure (array for ports)")
print("Fixed code:")
print("""
service = Service(
name="my-service",
namespace="default",
selector={"app": "nginx"},
ports=[{"port": 80, "targetPort": 80}] # Correct array structure
)
""")
def case_5_debugging_complex_errors():
"""Case 5: Debugging complex validation errors"""
print_error_case(
title="Debugging Complex Errors", description="How to understand and fix multi-level validation errors"
)
print("When you get a complex error, look for:")
print("1. The path to the error (e.g., 'spec.template.spec.containers[0]')")
print("2. The specific validation rule that failed")
print("3. The actual vs expected value/type")
# Example of complex error
print("\nExample complex error:")
deployment_dict = {
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {"name": "complex-deployment"},
"spec": {
"selector": {"matchLabels": {"app": "test"}},
"template": {
"metadata": {"labels": {"app": "test"}},
"spec": {
"containers": [
{
"name": "app",
"image": "myapp:latest",
"resources": {
"limits": {
"memory": 100 # Should be string with units
}
},
}
]
},
},
},
}
try:
Deployment.validate_dict(resource_dict=deployment_dict)
except ValidationError as e:
print(f"Error: {e}")
print_solution(solution="Follow the error path and fix the specific issue")
print("In this case: memory should be a string with units (e.g., '100Mi')")
def case_6_validation_performance():
"""Case 6: Validation performance tips"""
print_error_case(title="Performance Considerations", description="Tips for optimal validation performance")
print("Performance tips:")
print("1. First validation loads schema (~25ms), subsequent are cached (~2ms)")
print("2. Pre-warm cache for critical resources at startup")
print("3. Disable auto-validation for bulk operations")
print("4. Use validate_dict() for pre-validation without creating objects")
print("\nExample - Pre-warming cache:")
print("""
# At application startup
def warmup_cache():
for resource_cls in [Pod, Deployment, Service]:
try:
resource_cls.validate_dict({
"apiVersion": "v1",
"kind": resource_cls.kind,
"metadata": {"name": "dummy"}
})
except ValidationError:
# Schema validation errors are expected during warmup
pass # Ignore validation errors, just loading schemas
except (ValueError, TypeError, AttributeError) as e:
# Handle potential errors from missing/malformed data
print(f"Warning: Failed to warmup cache for {resource_cls.kind}: {e}")
""")
def main():
"""Run all troubleshooting cases"""
print("\n" + "=" * 60)
print(" Validation Troubleshooting Guide")
print("=" * 60)
cases = [
case_1_missing_required_fields,
case_2_wrong_types,
case_3_invalid_field_values,
case_4_invalid_structure,
case_5_debugging_complex_errors,
case_6_validation_performance,
]
for case in cases:
try:
case()
except Exception as e:
print(f"\nUnexpected error in case: {e}")
print("\n" + "=" * 60)
print(" Common Validation Error Patterns:")
print("=" * 60)
print("""
1. 'None is not of type X' → Required field is missing
2. 'X is not of type Y' → Wrong data type used
3. 'Does not match pattern' → Invalid format (e.g., DNS names)
4. 'X is not one of [Y, Z]' → Invalid enum value
5. 'Additional properties not allowed' → Unknown field name
6. 'X is less than Y' → Value outside allowed range
""")
print("\n✨ Remember: Validation errors are your friend!")
print(" They catch issues before they reach the Kubernetes API,")
print(" saving time and preventing failed deployments.")
if __name__ == "__main__":
main()