mirror of
https://github.com/replicatedhq/troubleshoot.git
synced 2026-09-03 00:47:17 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3f289b7449 | ||
|
|
ea7b6c8839 | ||
|
|
4cd8db07c8 | ||
|
|
132d042e79 | ||
|
|
d41d350097 | ||
|
|
dc1687a76a | ||
|
|
0f3f827974 | ||
|
|
71c9345157 | ||
|
|
181fa16b6c | ||
|
|
71d54c0d25 | ||
|
|
ffa242c2f1 | ||
|
|
e481adf017 | ||
|
|
43ef7e8f76 | ||
|
|
61722e0d47 | ||
|
|
6eb9c7096f | ||
|
+3 |
e9fac00516 | ||
|
|
b687656436 | ||
|
|
e02fae86c3 | ||
|
|
ae58bea4df | ||
|
|
96a8b2a713 | ||
|
|
df45d16c2c | ||
|
|
880739d885 | ||
|
|
553b75f8f0 | ||
|
|
d17e5d9a6d | ||
|
|
8fe5bffae4 | ||
|
|
79f8e6efab | ||
|
|
26d176a994 | ||
|
|
cbd648af05 | ||
|
|
a2bddc3f3b | ||
|
|
d85f7798f3 | ||
|
|
7b5b03e16d | ||
|
|
e45cff86e2 | ||
|
|
f3db02a200 | ||
|
|
5b51018541 | ||
|
|
617ddf11d9 | ||
|
|
3419a9b888 | ||
|
|
7b56ed4e51 | ||
|
|
d21e4855e7 | ||
|
|
6cc48f4751 | ||
|
|
546ffde14b | ||
|
|
299258ef87 | ||
|
|
c4f2dc9339 | ||
|
|
93e5ca8eaa | ||
|
|
777224f4c3 | ||
|
|
9f6739fdbe | ||
|
|
661a948d86 | ||
|
|
0bd6b88f04 | ||
|
|
c6f7cb6df0 | ||
|
|
c640a01e9f | ||
|
|
8871e53584 | ||
|
|
e85e91e784 | ||
|
|
752dacd5ed | ||
|
|
49fe355086 | ||
|
|
b8680102e5 | ||
|
|
b1d1b89068 | ||
|
|
100f9a13b6 | ||
|
|
e156b8c215 | ||
|
|
1114902707 | ||
|
|
4fca6aff98 | ||
|
|
f27c64cf85 | ||
|
|
0f6e6335fb | ||
|
|
925e94ad98 | ||
|
|
5bc3c33ee8 | ||
|
|
271e2d2af9 | ||
|
|
48ff918fcd | ||
|
|
dcb91673b5 | ||
|
|
c62e71a578 | ||
|
|
a8da38dd15 | ||
|
|
1756df905f | ||
|
|
2fcdc77cd3 | ||
|
|
ad1a56251f | ||
|
|
cf4eed1110 | ||
|
|
4939559789 | ||
|
|
533d2917a9 | ||
|
|
c8d9864235 | ||
|
|
827c49ca00 | ||
|
|
de0371053a | ||
|
|
2b4bcd2433 | ||
|
|
d9f4dca6b7 | ||
|
|
76922ee59b | ||
|
|
4965941ea9 | ||
|
|
18c4a39826 | ||
|
|
962e2c7d7e | ||
|
|
f1066f5d76 | ||
|
|
70af0ff3d0 | ||
|
|
4601db58f9 | ||
|
|
ddc07e1205 | ||
|
|
251fcc6dec | ||
|
|
75eb0d7f89 | ||
|
|
199efca2ea | ||
|
|
a442ac8fc4 | ||
|
|
a31e2ff1b9 | ||
|
|
87c153cc8c | ||
|
|
8ba5d6f6cb | ||
|
|
a523551da9 | ||
|
|
d73d5c6a3a | ||
|
|
8cb922c3b9 | ||
|
|
94dd7a670c | ||
|
|
0f2892c316 | ||
|
|
df43c9fc21 | ||
|
|
ebeed77287 | ||
|
|
bc6528908f | ||
|
|
e2053a00a2 | ||
|
|
421cccf919 | ||
|
|
be26462c19 | ||
|
|
13534bf7fd | ||
|
|
60b4931295 | ||
|
|
e48fa36eaf | ||
|
|
f2be6f5829 | ||
|
|
cd1511a8fb | ||
|
|
9c77a0e3da | ||
|
|
c8820b3d8e | ||
|
|
cf3a292877 | ||
|
|
a4c4b24056 | ||
|
|
e9f386a840 | ||
|
|
d96b2ded78 | ||
|
|
8c31e61367 | ||
|
|
8e174fb46c | ||
|
|
2a61a8686a | ||
|
|
c85bf9a9a6 | ||
|
|
bfb77ad601 | ||
|
|
c4c66633e5 | ||
|
|
f13a9598b2 | ||
|
|
4fa8411259 | ||
|
|
b693e6650d | ||
|
|
7e3a59cfc0 | ||
|
|
48faf0c144 | ||
|
|
fbbcf87405 | ||
|
|
6530cb364f | ||
|
|
c9b48aa716 | ||
|
|
511671f699 | ||
|
|
7a3bcfc74a | ||
|
|
e88f309391 | ||
|
|
da48621eff | ||
|
|
e51a25dc2f | ||
|
|
7a20aa1934 | ||
|
|
78bcafe489 | ||
|
|
233966d4be | ||
|
|
ebc569fcdb | ||
|
|
0521b0e82b | ||
|
|
34f29f2914 | ||
|
|
1de1d00680 | ||
|
|
92a5f3569f | ||
|
|
495b1a760d | ||
|
|
7bcfd01d43 | ||
|
|
f2ffef80af | ||
|
|
a5244a262c | ||
|
|
18d9a16ceb | ||
|
|
473738d709 | ||
|
|
c34d80c300 | ||
|
|
38c1193ace | ||
|
|
6b87cdb267 | ||
|
|
80cca8a487 | ||
|
|
6e79c169e0 | ||
|
|
7edbec3e45 | ||
|
|
8f8e0dc6e3 | ||
|
|
e2c20cfda4 | ||
|
|
ccb7b1619b | ||
|
|
d5c0dd4857 | ||
|
|
8c5cd5a460 | ||
|
|
9073a14c02 | ||
|
|
3513eeca19 | ||
|
|
34817b67d0 | ||
|
|
388e7ca77d | ||
|
|
d8091909b3 | ||
|
|
9ae416ab23 | ||
|
|
e373c71874 | ||
|
|
e2ac7bf715 | ||
|
|
3d4bd4b601 | ||
|
|
3b2aae1866 | ||
|
|
8a4f539173 | ||
|
|
89b98c197e | ||
|
|
000abae68b | ||
|
|
764f0ac8b6 | ||
|
|
04c7a18da3 | ||
|
|
9b37b98a93 | ||
|
|
32f622a714 | ||
|
|
bcaaa9e59a | ||
|
|
2298ec3030 | ||
|
|
afa2eb552a | ||
|
|
771058980a | ||
|
|
d789119634 | ||
|
|
48beb303be | ||
|
|
e30d279cad | ||
|
|
9c986a74a6 | ||
|
|
e02074941e | ||
|
|
56a68a4fef | ||
|
|
b3e662c988 | ||
|
|
a0fb06f0b9 | ||
|
|
906fa88119 | ||
|
|
eb40b9422f | ||
|
|
f6531b8434 | ||
|
|
e80235f0a8 | ||
|
|
c7b84ad1e5 | ||
|
|
44ae409081 | ||
|
|
d1318ff4fd | ||
|
|
169f3c6ea7 | ||
|
|
7a7507b5e4 | ||
|
|
d5c7522be5 | ||
|
|
f5b6a108a1 | ||
|
|
c4746e766b | ||
|
|
4fadd471e6 | ||
|
|
c397171b79 | ||
|
|
a20f9d9408 | ||
|
|
ebd49e70df | ||
|
|
b66145e514 | ||
|
|
be070c98e1 | ||
|
|
7eecf6c526 | ||
|
|
126346e1fe | ||
|
|
e7fe012f2f | ||
|
|
ec6ec59303 | ||
|
|
e53871b4dc | ||
|
|
93da8b6ac7 | ||
|
|
ad4cfc6d9e | ||
|
|
ad23763d6b | ||
|
|
7120516b13 | ||
|
|
ed34afc51b | ||
|
|
d4e5c0dba4 | ||
|
|
a50263c725 | ||
|
|
818a9bc9a2 | ||
|
|
e98497b78b | ||
|
|
60c2547cc0 | ||
|
|
934bf8ed87 | ||
|
|
05d3e66de9 | ||
|
|
d70ecf7e5f | ||
|
|
7403e39210 | ||
|
|
92382e600f | ||
|
|
b5a56e5239 | ||
|
|
b6f8ac211e | ||
|
|
63510fc89d | ||
|
|
91c387b0ca | ||
|
|
8fcb65d2a6 | ||
|
|
b2c3280623 | ||
|
|
cdf4d730d4 | ||
|
|
ca9bc007e5 | ||
|
|
f082ef43dc | ||
|
|
fb71cd4ef6 | ||
|
|
92dc66f338 | ||
|
|
e3553198d1 | ||
|
|
a4f57ec3c9 | ||
|
|
e5a7409b5e | ||
|
|
2a1108776e | ||
|
|
eeac031e70 | ||
|
|
7e77cb9723 | ||
|
|
1495214261 | ||
|
|
e75a3a07b9 | ||
|
|
f6bffb6982 | ||
|
|
a9e3a6ba1c | ||
|
|
0fb2026192 | ||
|
|
1b4caf3592 | ||
|
|
8dc4ac1732 | ||
|
|
c027ed9c1b | ||
|
|
b11dd5ff73 | ||
|
|
8bdb09ff7d | ||
|
|
b20a8e5321 | ||
|
|
1c9d3510cd | ||
|
|
ec246a62b9 | ||
|
|
f5652df9da | ||
|
|
b716374070 | ||
|
|
1a637f3c4f | ||
|
|
3b3ae4e7bf | ||
|
|
414bf84c68 | ||
|
|
b3ee989cfe | ||
|
|
eea128856c | ||
|
|
4517030473 | ||
|
|
c3773b7f26 | ||
|
|
fa2daa70b1 | ||
|
|
6adc5b3c7f | ||
|
|
a46548c119 | ||
|
|
3a5b65dec4 | ||
|
|
a463403bde | ||
|
|
75bc9d576c | ||
|
|
6a08536556 | ||
|
|
330263aae8 | ||
|
|
052a8656ba | ||
|
|
f1d0e3ce0d | ||
|
|
ed0d252f39 | ||
|
|
56126fb602 | ||
|
|
f58080b604 | ||
|
|
1a488eabc2 | ||
|
|
67cc83fa9a | ||
|
|
a91ef9edfe | ||
|
|
007609565a | ||
|
|
6319d2a264 | ||
|
|
f6afe7e7e9 | ||
|
|
f06201e050 | ||
|
|
661bc3a557 | ||
|
|
114749d5b7 | ||
|
|
4f8c1f3d8b | ||
|
|
14f9ae8f3b | ||
|
|
248b393288 | ||
|
|
6fe887df62 | ||
|
|
65c8980504 | ||
|
|
41d2bae380 | ||
|
|
912e76c97e | ||
|
|
f6e49c95f9 | ||
|
|
85aa5334b0 | ||
|
|
29e817475a | ||
|
|
e0caefc9df | ||
|
|
09eef9019f | ||
|
|
057be29943 | ||
|
|
4ec239e94f | ||
|
|
11b54a2ed3 | ||
|
|
33a92a81e4 | ||
|
|
5f11410677 | ||
|
|
6b076a7d4d | ||
|
|
0070a5fb10 | ||
|
|
be47f06217 | ||
|
|
16e395b90a | ||
|
|
ef1a186f9e | ||
|
|
5ade1cb4b6 | ||
|
|
8b90f2595d | ||
|
|
f98fa5c637 | ||
|
|
f21ba951a5 | ||
|
|
5bae5efb92 | ||
|
|
5568f241a3 | ||
|
|
19f66574c6 | ||
|
|
ae75f325c2 | ||
|
|
28cad0cf4a | ||
|
|
83d7e48999 | ||
|
|
e2d1ce2fb0 | ||
|
|
e6cc4e6c47 | ||
|
|
8c0c83776f | ||
|
|
ae888134a3 | ||
|
|
276cf7ce06 | ||
|
|
7132ee7405 | ||
|
|
817ebaad41 | ||
|
|
9e90e94ced | ||
|
|
fd1594520e | ||
|
|
9b6f8d3aff | ||
|
|
d84a919b33 | ||
|
|
fc745c1144 | ||
|
|
8f38b7c5aa | ||
|
|
0203889171 | ||
|
|
78c93418ca | ||
|
|
c1d303350f | ||
|
|
642d098238 | ||
|
|
532f1583b5 | ||
|
|
ab42cd766f | ||
|
|
050345f123 | ||
|
|
8e7ea022f7 | ||
|
|
c1c772e59f | ||
|
|
a1533d5ec5 | ||
|
|
1820c40c43 | ||
|
|
cab3fc7f4e | ||
|
|
3ff0e82fcc | ||
|
|
40f1f0193a | ||
|
|
2de46a18a5 | ||
|
|
cdbf189955 | ||
|
|
ff5ee2b709 | ||
|
|
d98c01a3b9 | ||
|
|
0996b3b1ad | ||
|
|
b617de3fd0 | ||
|
|
c9c305570b | ||
|
|
601bf75ceb | ||
|
|
fe1137d8ec | ||
|
|
69b34c45b2 | ||
|
|
f1cff2cd74 | ||
|
|
0f2976cac5 | ||
|
|
65570ac121 | ||
|
|
4acd7e4951 | ||
|
|
7b4bfa3af7 | ||
|
|
43a936a0d7 | ||
|
|
27479e856f | ||
|
|
567fa5950c | ||
|
|
b29ef61cc5 | ||
|
|
34c59eb237 | ||
|
|
650916f77c | ||
|
|
7ec008479a | ||
|
|
f02566c712 | ||
|
|
354a996edc | ||
|
|
31d6a0d8fd | ||
|
|
1de5a79855 | ||
|
|
b308f4a2b2 | ||
|
|
33ddee27ed | ||
|
|
6d7bf73aba | ||
|
|
a5fceaf476 | ||
|
|
1e2e7e9aee | ||
|
|
319a3a8d38 | ||
|
|
5e7bd06fcb | ||
|
|
b92037171e | ||
|
|
fc52426a4a | ||
|
|
3a5816cd18 | ||
|
|
7c74f8b755 | ||
|
|
a881877fd8 | ||
|
|
c044cc6021 | ||
|
|
009829c3ff | ||
|
|
4404849e76 | ||
|
|
374a65522d | ||
|
|
5da84663b1 | ||
|
|
0bbf2dff48 | ||
|
|
156965fd10 | ||
|
|
3da43b18c9 | ||
|
|
78314a5fc4 | ||
|
|
9792289ac1 | ||
|
|
6018068349 | ||
|
|
7f829bb3ca | ||
|
|
d3cf4fc7f4 | ||
|
|
e85e9cd464 | ||
|
|
a0a6a5bf19 | ||
|
|
750ebc1277 | ||
|
|
6f997a47a3 | ||
|
|
af1afd09ca | ||
|
|
74b4802b46 | ||
|
|
c31b803092 | ||
|
|
84b40804b5 | ||
|
|
3d6841c11e | ||
|
|
8adf58b717 | ||
|
|
44c07c2a00 | ||
|
|
9179dc8fec | ||
|
|
a9df4552b4 | ||
|
|
c5505bc017 | ||
|
|
3ceffbc4b2 | ||
|
|
5967105ad2 | ||
|
|
7eb6263dc1 | ||
|
|
249e52d3da | ||
|
|
6b5b9297ba | ||
|
|
8c15bb1fae | ||
|
|
d2d19a2490 | ||
|
|
5c269e2aaf | ||
|
|
30fb4e2108 | ||
|
|
24096b0272 | ||
|
|
cccc9f23a1 | ||
|
|
ff4353817f | ||
|
|
c2136fcea0 | ||
|
|
9898d3fbb2 | ||
|
|
5ec3524bde | ||
|
|
a471ad5e74 | ||
|
|
7b30e283ea | ||
|
|
8c62aadcfc | ||
|
|
e7f2685ed8 | ||
|
|
3b1ba08a6b | ||
|
|
17fe3db79f | ||
|
|
9ec9806b62 | ||
|
|
061ce1d2eb | ||
|
|
0f56baf4dc | ||
|
|
d6a17951d3 | ||
|
|
9f527ee6a5 | ||
|
|
2c9a37a4f1 | ||
|
|
e6e9df1773 | ||
|
|
755220cd4c | ||
|
|
7289134757 | ||
|
|
63362d32ee | ||
|
|
6cdcb36127 | ||
|
|
dfe5538132 | ||
|
|
42902405cd | ||
|
|
2516924a92 | ||
|
|
ce4165f69e | ||
|
|
648f9b8d35 | ||
|
|
aeb89e57a7 | ||
|
|
8d1a0f6d24 | ||
|
|
0cfd431274 | ||
|
|
fe5dd3ee8f | ||
|
|
7eb1d5a5fb | ||
|
|
40cdc6805e | ||
|
|
3d7a255e32 | ||
|
|
77a2475bd2 | ||
|
|
7bfb54360c | ||
|
|
ca0b3c31c1 | ||
|
|
2b774e16d7 | ||
|
|
9d41d4a7be | ||
|
|
e248ab0f97 | ||
|
|
942234da80 | ||
|
|
0a2ed01a46 | ||
|
|
a818417e8c | ||
|
|
f9039a0fb5 | ||
|
|
3351c289ab | ||
|
|
6f0cf6550d | ||
|
|
7425f583fc | ||
|
|
c3af3b63d9 | ||
|
|
8fc7d12e19 | ||
|
|
877e43dd47 | ||
|
|
e18d273205 | ||
|
|
3d97d8e5a6 | ||
|
|
137b0cee14 | ||
|
|
007edd1181 | ||
|
|
3cedbe16a7 | ||
|
|
46cfa14598 | ||
|
|
4c72573936 | ||
|
|
347d462d7f | ||
|
|
d1f341b8ed |
@@ -0,0 +1,4 @@
|
||||
version: 3
|
||||
|
||||
project:
|
||||
id: github.com/replicatedhq/troubleshoot
|
||||
+17
-1
@@ -1 +1,17 @@
|
||||
* @replicatedhq/day2
|
||||
# Lines starting with '#' are comments.
|
||||
# Each line is a file pattern followed by one or more owners.
|
||||
|
||||
# More details are here: https://help.github.com/articles/about-codeowners/
|
||||
|
||||
# The '*' pattern is global owners.
|
||||
|
||||
# Order is important. The last matching pattern has the most precedence.
|
||||
# The folders are ordered as follows:
|
||||
|
||||
# In each subsection folders are ordered first by depth, then alphabetically.
|
||||
# This should make it easy to add new rules without breaking existing ones.
|
||||
|
||||
## RULES
|
||||
|
||||
* @replicatedhq/troubleshoot
|
||||
*.md @replicatedhq/cre
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
name: Feature Epic
|
||||
about: Create a tracking issue for a change that is larger than a single task
|
||||
labels: 'epic'
|
||||
|
||||
---
|
||||
|
||||
# Design Proposal
|
||||
|
||||
Link to the [proposal](https://github.com/replicatedhq/troubleshoot/tree/main/design/template.md)
|
||||
|
||||
# Definition of done
|
||||
|
||||
Describe what specific goals can measure if this overall task is considered completed. Things to consider are documentation, high level description of the feature working, and tests.
|
||||
|
||||
* [ ]
|
||||
|
||||
# Subtasks
|
||||
|
||||
Create a list of the smaller tasks to implement this design. Task can start as simple descriptions but should be converted to issues before work is started.
|
||||
|
||||
## Started
|
||||
|
||||
* [ ]
|
||||
|
||||
## Planned
|
||||
|
||||
* [ ]
|
||||
@@ -7,11 +7,11 @@ labels: 'feature'
|
||||
|
||||
**Describe the rationale for the suggested feature.**
|
||||
|
||||
Insert a description of the rationale for the new feature here. For example, you could describe a problem that Troubleshoot doesn't address, a limitation, or an idea to improve Troubleshoot.
|
||||
Insert a description of the rationale for the new feature here. For example, you could describe a problem that Troubleshoot doesn't address, a limitation, or an idea to improve Troubleshoot.
|
||||
|
||||
**Describe the feature**
|
||||
|
||||
Insert a description of the feature here. Be specific about how it addresses the any problems, limitations, or suggested improvements outlined in the rationale for the feature.
|
||||
Insert a description of the feature here. Be specific about how it addresses the problem. Mention any limitations, or suggested improvements outlined in the rationale for the feature.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
|
||||
@@ -19,4 +19,4 @@ Describe alternative solutions here. Include any workarounds you've considered.
|
||||
|
||||
**Additional context**
|
||||
|
||||
Add additional context about the feature request. If the change is substantial, consider attaching files to the issue outlining architectural changes, data flows, file formats etc., anything that helps describe the requested change.
|
||||
Add additional context about the feature request. If the change is substantial, consider attaching files to the issue outlining architectural changes, data flows, file formats etc., anything that helps describe the requested change.
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
## Description, Motivation and Context
|
||||
|
||||
Please include a summary of the change or what problem it solves. Please also include relevant motivation and context.
|
||||
|
||||
<!--- If it relates to an open issue, please link to the issue here.
|
||||
e.g.
|
||||
Fixes: #414
|
||||
-->
|
||||
|
||||
## Checklist
|
||||
|
||||
- [ ] New and existing tests pass locally with introduced changes.
|
||||
- [ ] Tests for the changes have been added (for bug fixes / features)
|
||||
- [ ] The commit message(s) are informative and highlight any breaking changes
|
||||
- [ ] Any documentation required has been added/updated. For changes to https://troubleshoot.sh/ create a PR [here](https://github.com/replicatedhq/troubleshoot.sh/pulls)
|
||||
|
||||
## Does this PR introduce a breaking change?
|
||||
- [ ] Yes
|
||||
- [ ] No
|
||||
|
||||
<!-- If this PR contains a breaking change, please describe the impact and migration path for existing applications below. -->
|
||||
@@ -13,3 +13,15 @@ updates:
|
||||
- "type::chore"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
|
||||
# Maintain dependencies for GitHub Actions
|
||||
- package-ecosystem: "github-actions"
|
||||
# Workflow files stored in the
|
||||
# default location of `.github/workflows`
|
||||
directory: "/"
|
||||
labels:
|
||||
- "dependencies"
|
||||
- "github-actions"
|
||||
- "type::chore"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
|
||||
@@ -1,20 +1,36 @@
|
||||
on:
|
||||
pull_request:
|
||||
types:
|
||||
- opened
|
||||
- reopened
|
||||
- synchronize
|
||||
- ready_for_review
|
||||
branches:
|
||||
- master
|
||||
- main
|
||||
push:
|
||||
branches:
|
||||
- "master"
|
||||
- "main"
|
||||
tags:
|
||||
- "v*.*.*"
|
||||
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-18.04
|
||||
fail_if_pull_request_is_draft:
|
||||
if: github.event.pull_request.draft == true
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/setup-go@v1
|
||||
- name: Fails in order to indicate that pull request needs to be marked as ready to review and unit tests workflow needs to pass.
|
||||
run: exit 1
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: "1.17"
|
||||
go-version: "1.19"
|
||||
|
||||
- name: setup env
|
||||
run: |
|
||||
@@ -22,39 +38,76 @@ jobs:
|
||||
echo "$(go env GOPATH)/bin" >> $GITHUB_PATH
|
||||
shell: bash
|
||||
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- run: make test
|
||||
|
||||
test-integration:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: "1.19"
|
||||
|
||||
- name: setup env
|
||||
run: |
|
||||
echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV
|
||||
echo "$(go env GOPATH)/bin" >> $GITHUB_PATH
|
||||
shell: bash
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
- uses: replicatedhq/action-k3s@main
|
||||
id: k3s
|
||||
with:
|
||||
version: v1.23.6-k3s1
|
||||
|
||||
- run: make test-integration
|
||||
|
||||
ensure-schemas-are-generated:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: "1.19"
|
||||
- name: setup env
|
||||
run: |
|
||||
echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV
|
||||
echo "$(go env GOPATH)/bin" >> $GITHUB_PATH
|
||||
shell: bash
|
||||
- uses: actions/checkout@v3
|
||||
- run: make check-schemas
|
||||
|
||||
- run: make
|
||||
|
||||
compile-preflight:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
steps:
|
||||
- uses: actions/setup-go@v1
|
||||
- uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: '1.17'
|
||||
go-version: "1.19"
|
||||
- name: setup env
|
||||
run: |
|
||||
echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV
|
||||
echo "$(go env GOPATH)/bin" >> $GITHUB_PATH
|
||||
shell: bash
|
||||
- uses: actions/checkout@master
|
||||
- run: make preflight
|
||||
- uses: actions/upload-artifact@v1
|
||||
- uses: actions/checkout@v3
|
||||
- run: make generate preflight
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: preflight
|
||||
path: bin/preflight
|
||||
|
||||
|
||||
validate-preflight:
|
||||
runs-on: ubuntu-latest
|
||||
needs: compile-preflight
|
||||
steps:
|
||||
- uses: replicatedhq/action-k3s@main
|
||||
id: k3s
|
||||
with:
|
||||
version: v1.23.6-k3s1
|
||||
- name: Download preflight binary
|
||||
uses: actions/download-artifact@v1
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: preflight
|
||||
path: bin/
|
||||
- uses: engineerd/setup-kind@v0.5.0
|
||||
- run: chmod +x bin/preflight
|
||||
- run: |
|
||||
./bin/preflight --interactive=false --format=json https://preflight.replicated.com > result.json
|
||||
@@ -83,21 +136,37 @@ jobs:
|
||||
|
||||
exit $EXIT_STATUS
|
||||
|
||||
validate-preflight-e2e:
|
||||
runs-on: ubuntu-latest
|
||||
needs: compile-preflight
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: replicatedhq/action-k3s@main
|
||||
id: k3s
|
||||
with:
|
||||
version: v1.23.6-k3s1
|
||||
- name: Download preflight binary
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: preflight
|
||||
path: bin/
|
||||
- run: chmod +x bin/preflight
|
||||
- run: make preflight-e2e-test
|
||||
|
||||
compile-supportbundle:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
steps:
|
||||
- uses: actions/setup-go@v1
|
||||
- uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: '1.17'
|
||||
go-version: "1.19"
|
||||
- name: setup env
|
||||
run: |
|
||||
echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV
|
||||
echo "$(go env GOPATH)/bin" >> $GITHUB_PATH
|
||||
shell: bash
|
||||
- uses: actions/checkout@master
|
||||
- run: make support-bundle
|
||||
- uses: actions/upload-artifact@v1
|
||||
- uses: actions/checkout@v3
|
||||
- run: make generate support-bundle
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: support-bundle
|
||||
path: bin/support-bundle
|
||||
@@ -106,58 +175,106 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
needs: compile-supportbundle
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/checkout@v3
|
||||
- uses: replicatedhq/action-k3s@main
|
||||
id: k3s
|
||||
with:
|
||||
version: v1.23.6-k3s1
|
||||
- name: Download support-bundle binary
|
||||
uses: actions/download-artifact@v1
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: support-bundle
|
||||
path: bin/
|
||||
- uses: engineerd/setup-kind@v0.5.0
|
||||
- run: chmod +x bin/support-bundle
|
||||
- run: ./bin/support-bundle ./examples/support-bundle/sample-collectors.yaml
|
||||
- run: ./bin/support-bundle ./examples/support-bundle/sample-supportbundle.yaml
|
||||
- run: ./bin/support-bundle https://kots.io
|
||||
|
||||
validate-supportbundle-e2e:
|
||||
runs-on: ubuntu-latest
|
||||
needs: compile-supportbundle
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: replicatedhq/action-k3s@main
|
||||
id: k3s
|
||||
with:
|
||||
version: v1.23.6-k3s1
|
||||
- name: Download support bundle binary
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: support-bundle
|
||||
path: bin/
|
||||
- run: chmod +x bin/support-bundle
|
||||
- run: make support-bundle-e2e-test
|
||||
|
||||
compile-collect:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: "1.19"
|
||||
- name: setup env
|
||||
run: |
|
||||
echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV
|
||||
echo "$(go env GOPATH)/bin" >> $GITHUB_PATH
|
||||
shell: bash
|
||||
- uses: actions/checkout@v3
|
||||
- run: make generate collect
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: collect
|
||||
path: bin/collect
|
||||
|
||||
goreleaser-test:
|
||||
runs-on: ubuntu-latest
|
||||
if: startsWith(github.ref, 'refs/tags/v') != true
|
||||
strategy:
|
||||
matrix:
|
||||
goarch: [amd64, arm64]
|
||||
goos: [darwin, linux, windows]
|
||||
include:
|
||||
- goarch: arm
|
||||
goos: linux
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Unshallow
|
||||
run: git fetch --prune --unshallow
|
||||
|
||||
- uses: actions/setup-go@v1
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
go-version: "1.17"
|
||||
fetch-depth: 0
|
||||
|
||||
- uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: "1.19"
|
||||
|
||||
- name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v2
|
||||
uses: goreleaser/goreleaser-action@v4
|
||||
with:
|
||||
version: "v0.183.0"
|
||||
args: build --rm-dist --snapshot --config deploy/.goreleaser.yaml
|
||||
args: build --rm-dist --snapshot --config deploy/.goreleaser.yaml --single-target
|
||||
env:
|
||||
GOARCH: ${{ matrix.goarch }}
|
||||
GOOS: ${{ matrix.goos }}
|
||||
|
||||
goreleaser:
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- validate-preflight
|
||||
- validate-preflight-e2e
|
||||
- validate-supportbundle
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- uses: azure/docker-login@v1
|
||||
with:
|
||||
username: repldeploy2
|
||||
username: ${{ secrets.DOCKERHUB_USER }}
|
||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||
|
||||
- name: Unshallow
|
||||
run: git fetch --prune --unshallow
|
||||
|
||||
- uses: actions/setup-go@v1
|
||||
- uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: "1.17"
|
||||
go-version: "1.19"
|
||||
|
||||
- uses: sigstore/cosign-installer@main
|
||||
with:
|
||||
@@ -168,28 +285,27 @@ jobs:
|
||||
echo $COSIGN_KEY | base64 -d > ./cosign.key
|
||||
env:
|
||||
COSIGN_KEY: ${{secrets.COSIGN_KEY}}
|
||||
|
||||
|
||||
- name: Generate SBOM
|
||||
run: |
|
||||
make sbom
|
||||
env:
|
||||
COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }}
|
||||
COSIGN_KEY: ${{ secrets.COSIGN_KEY }}
|
||||
|
||||
|
||||
- name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v2
|
||||
uses: goreleaser/goreleaser-action@v4
|
||||
with:
|
||||
version: "v0.183.0"
|
||||
args: release --rm-dist --config deploy/.goreleaser.yaml
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
|
||||
- name: Update new preflight version in krew-index
|
||||
uses: rajatjindal/krew-release-bot@v0.0.38
|
||||
uses: rajatjindal/krew-release-bot@v0.0.46
|
||||
with:
|
||||
krew_template_file: deploy/krew/preflight.yaml
|
||||
- name: Update new support-bundle version in krew-index
|
||||
uses: rajatjindal/krew-release-bot@v0.0.38
|
||||
uses: rajatjindal/krew-release-bot@v0.0.46
|
||||
with:
|
||||
krew_template_file: deploy/krew/support-bundle.yaml
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
name: Scan vulnerabilities
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
scan_troubleshoot_files_systems:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Run Trivy vulnerability scanner in repo mode
|
||||
uses: aquasecurity/trivy-action@master
|
||||
with:
|
||||
scan-type: 'fs'
|
||||
ignore-unfixed: true
|
||||
format: 'sarif'
|
||||
output: 'trivy-results.sarif'
|
||||
severity: 'HIGH,CRITICAL'
|
||||
|
||||
- name: Upload Trivy scan results to GitHub Security tab
|
||||
uses: github/codeql-action/upload-sarif@v2
|
||||
with:
|
||||
sarif_file: 'trivy-results.sarif'
|
||||
@@ -0,0 +1,18 @@
|
||||
name: PR license scan
|
||||
|
||||
on:
|
||||
pull_request_target: # this is safe as these scans do not execute provided code
|
||||
|
||||
jobs:
|
||||
fossa-scan:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
ref: refs/pull/${{ github.event.number }}/merge
|
||||
- name: "Install FOSSA"
|
||||
uses: replicatedhq/action-fossa/install@main
|
||||
- name: "Run FOSSA Scan"
|
||||
uses: replicatedhq/action-fossa/scan@main
|
||||
with:
|
||||
api-key: ${{ secrets.FOSSA_API_KEY }}
|
||||
@@ -6,6 +6,7 @@
|
||||
*.so
|
||||
*.dylib
|
||||
bin
|
||||
.DS_Store
|
||||
|
||||
# Test binary, build with `go test -c`
|
||||
*.test
|
||||
@@ -34,3 +35,10 @@ workspace.*
|
||||
|
||||
cosign.key
|
||||
sbom/
|
||||
|
||||
# Ignore local pre-commit config
|
||||
.pre-commit-config.yaml
|
||||
|
||||
# Ignore generated support bundles
|
||||
*.tar.gz
|
||||
!testdata/supportbundle/*.tar.gz
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
# https://golangci-lint.run/usage/configuration/#config-file
|
||||
|
||||
run:
|
||||
allow-parallel-runners: true
|
||||
timeout: 30s
|
||||
|
||||
linters:
|
||||
enable:
|
||||
- gocritic
|
||||
- gocyclo
|
||||
- gofmt
|
||||
- gosec
|
||||
+101
-5
@@ -1,11 +1,107 @@
|
||||
# Contributing to Troubleshoot
|
||||
|
||||
Thank you for your interest in Troubleshoot, we welcome your participation. Please familiarize yourself with our [Code of Conduct](https://github.com/replicatedhq/troubleshoot/blob/master/CODE_OF_CONDUCT.md) prior to contributing. There are a number of ways to participate in Troubleshoot as outlined below:
|
||||
Thank you for your interest in Troubleshoot, we welcome your participation. Please familiarize yourself with our [Code of Conduct](https://github.com/replicatedhq/troubleshoot/blob/main/CODE_OF_CONDUCT.md) prior to contributing. There are a number of ways to participate in Troubleshoot as outlined below:
|
||||
|
||||
# Community
|
||||
|
||||
For discussions about developing Troubleshoot, there's an [#app-troubleshoot channel in Kubernetes Slack](https://kubernetes.slack.com/channels/app-troubleshoot), plus IRC using [Libera](ircs://irc.libera.chat:6697/#troubleshoot) (#troubleshoot).
|
||||
|
||||
There are [community meetings](https://calendar.google.com/calendar/u/0?cid=Y19mMGx1aGhiZGtscGllOGo5dWpicXMwNnN1a0Bncm91cC5jYWxlbmRhci5nb29nbGUuY29t) on a regular basis, with a shared calendar and [public notes](https://hackmd.io/yZbotEHdTg6TfRZBzb8Tcg)
|
||||
|
||||
## Issues
|
||||
- [Request a New Feature](https://github.com/replicatedhq/troubleshoot/issues/new?assignees=&labels=feature&template=feature_enhancement.md) Create an issue to add functionality that addresses a problem or adds an enhancement.
|
||||
- [Report a Bug](https://github.com/replicatedhq/troubleshoot/issues/new?assignees=&labels=bug&template=bug_report.md) Report a problem or unexpected behaviour with Troubleshoot.
|
||||
|
||||
## Pull Requests
|
||||
- [Request a New Feature](https://github.com/replicatedhq/troubleshoot/issues/new?assignees=&labels=feature&template=feature_enhancement.md) Create an issue to add functionality that addresses a problem or adds an enhancement.
|
||||
- [Report a Bug](https://github.com/replicatedhq/troubleshoot/issues/new?assignees=&labels=bug&template=bug_report.md) Report a problem or unexpected behaviour with Troubleshoot.
|
||||
|
||||
If you are interested in contributing a change to the code or documentation please open a pull request with your set of changes. The pull request will be reviewed in a timely manner.
|
||||
## Design Principles
|
||||
|
||||
When implementing a new feature please review the [design principles](./docs/design/design-principles.md) to help guide the approach.
|
||||
|
||||
## Development Environment
|
||||
|
||||
To get started we recommend:
|
||||
|
||||
1. Go (v1.19 or later)
|
||||
2. A Kubernetes cluster (we recommend <https://k3d.io/>. This requires Docker v20.10.5 or later)
|
||||
3. Fork and clone the repo to $GOPATH/src/github.com/replicatedhq/
|
||||
4. Run `make support-bundle preflight` to generate binaries
|
||||
5. Run `make run-troubleshoot` to generate a support bundle with the `sample-troubleshoot.yaml` in the root of the repo
|
||||
|
||||
> Note: recent versions of Go support easy cross-compilation. For example, to cross-compile a Linux binary from MacOS:
|
||||
> `GOOS=linux GOARCH=amd64 make support-bundle preflight`
|
||||
|
||||
6. Install [golangci-lint] linter and run `make lint` to execute additional code linters.
|
||||
|
||||
### Testing
|
||||
|
||||
To run the tests locally run the following:
|
||||
|
||||
```bash
|
||||
make test
|
||||
make test RUN=TestClusterResources_Merge
|
||||
```
|
||||
|
||||
Additionally, e2e tests can be run with:
|
||||
|
||||
```bash
|
||||
make support-bundle preflight e2e-test
|
||||
```
|
||||
|
||||
A running Kubernetes cluster as well as `jq` are required to run e2e tests.
|
||||
|
||||
### Profiling
|
||||
|
||||
You are able to collect CPU & memory runtime properties and store the data for analysis in a file. To do so, pass in the file paths using `--cpuprofile` and `--memprofile` flags in the CLI. Once you have your data collected, you can analyse it using [pprof visualization tool](https://github.com/google/pprof/blob/main/doc/README.md). Here is how
|
||||
|
||||
Run support bundle and with CPU & memory profile flags
|
||||
```sh
|
||||
./bin/support-bundle examples/support-bundle/sample-supportbundle.yaml --cpuprofile=cpu.prof --memprofile=mem.prof
|
||||
```
|
||||
|
||||
Visualize using [pprof](https://github.com/google/pprof/blob/main/doc/README.md)
|
||||
```sh
|
||||
go tool pprof -http=":8000" cpu.prof
|
||||
|
||||
go tool pprof -http=":8001" mem.prof
|
||||
```
|
||||
|
||||
More on profiling please visit https://go.dev/doc/diagnostics#profiling
|
||||
|
||||
## Contribution workflow
|
||||
|
||||
This is a rough outline of how to prepare a contribution:
|
||||
|
||||
- Create a fork of this repo.
|
||||
- Create a topic branch from where you want to base your work (branched from `main` is a safe choice).
|
||||
- Make commits of logical units.
|
||||
- When your changes are ready to merge, squash your history to 1 commit.
|
||||
- For example, if you want to squash your last 3 commits and write a new commit message:
|
||||
```
|
||||
git reset --soft HEAD~3 &&
|
||||
git commit
|
||||
```
|
||||
|
||||
- If you want to keep the previous commit messages and concatenate them all into a new commit, you can do something like this instead:
|
||||
```
|
||||
git reset --soft HEAD~3 &&
|
||||
git commit --edit -m"$(git log --format=%B --reverse HEAD..HEAD@{1})"
|
||||
```
|
||||
- Push your changes to a topic branch in your fork of the repository.
|
||||
- Submit a pull request to the original repository. It will be reviewed in a timely manner.
|
||||
|
||||
### Pull Requests
|
||||
|
||||
A pull request should address a single issue, feature or bug. For example, lets say you've written code that fixes two issues. That's great! However, you should submit two small pull requests, one for each issue as opposed to combining them into a single larger pull request. In general the size of the pull request should be kept small in order to make it easy for a reviewer to understand, and to minimize risks from integrating many changes at the same time. For example, if you are working on a large feature you should break it into several smaller PRs by implementing the feature as changes to several packages and submitting a separate pull request for each one. Squash commit history when preparing your PR so it merges as 1 commit.
|
||||
|
||||
Code submitted in pull requests must be properly documented, formatted and tested in order to be approved and merged. The following guidelines describe the things a reviewer will look for when they evaluate your pull request. Here's a tip. If your reviewer doesn't understand what the code is doing, they won't approve the pull request. Strive to make code clear and well documented. If possible, request a reviewer that has some context on the PR.
|
||||
|
||||
### Commit messages
|
||||
|
||||
Commit messages should follow the general guidelines:
|
||||
|
||||
- Breaking changes should be highlighted in the heading of the commit message.
|
||||
- Commits should be clear about their purpose (and a single commit per thing that changed)
|
||||
- Messages should be descriptive:
|
||||
- First line, 50 chars or less, as a heading/title that people can find
|
||||
- Then a paragraph explaining things
|
||||
- Consider a footer with links to which bugs they fix etc, bearing in mind that Github does some of this magic already
|
||||
|
||||
@@ -2,10 +2,11 @@
|
||||
# Image URL to use all building/pushing image targets
|
||||
IMG ?= controller:latest
|
||||
|
||||
SHELL := /bin/bash -o pipefail
|
||||
SHELL := bash -o pipefail
|
||||
VERSION_PACKAGE = github.com/replicatedhq/troubleshoot/pkg/version
|
||||
VERSION ?=`git describe --tags --dirty`
|
||||
DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"`
|
||||
RUN?=""
|
||||
|
||||
GIT_TREE = $(shell git rev-parse --is-inside-work-tree 2>/dev/null)
|
||||
ifneq "$(GIT_TREE)" ""
|
||||
@@ -34,46 +35,66 @@ define LDFLAGS
|
||||
endef
|
||||
|
||||
BUILDFLAGS = -tags "netgo containers_image_ostree_stub exclude_graphdriver_devicemapper exclude_graphdriver_btrfs containers_image_openpgp" -installsuffix netgo
|
||||
BUILDPATHS = ./pkg/... ./cmd/... ./internal/...
|
||||
|
||||
all: test
|
||||
all: test support-bundle preflight collect analyze
|
||||
|
||||
.PHONY: ffi
|
||||
ffi: fmt vet
|
||||
go build ${BUILDFLAGS} ${LDFLAGS} -o bin/troubleshoot.so -buildmode=c-shared ffi/main.go
|
||||
|
||||
# Run tests
|
||||
.PHONY: test
|
||||
test: generate fmt vet
|
||||
go test ${BUILDFLAGS} ./pkg/... ./cmd/... -coverprofile cover.out
|
||||
if [ -n $(RUN) ]; then \
|
||||
go test ${BUILDFLAGS} ${BUILDPATHS} -coverprofile cover.out -run $(RUN); \
|
||||
else \
|
||||
go test ${BUILDFLAGS} ${BUILDPATHS} -coverprofile cover.out; \
|
||||
fi
|
||||
|
||||
# Go tests that require a K8s instance
|
||||
# TODOLATER: merge with test, so we get unified coverage reports? it'll add 21~sec to the test job though...
|
||||
.PHONY: test-integration
|
||||
test-integration:
|
||||
go test -v --tags "integration exclude_graphdriver_devicemapper exclude_graphdriver_btrfs" ${BUILDPATHS}
|
||||
|
||||
.PHONY: preflight-e2e-test
|
||||
preflight-e2e-test:
|
||||
./test/validate-preflight-e2e.sh
|
||||
|
||||
.PHONY: support-bundle-e2e-test
|
||||
support-bundle-e2e-test:
|
||||
./test/validate-support-bundle-e2e.sh
|
||||
|
||||
.PHONY: support-bundle
|
||||
support-bundle: generate fmt vet
|
||||
support-bundle:
|
||||
go build ${BUILDFLAGS} ${LDFLAGS} -o bin/support-bundle github.com/replicatedhq/troubleshoot/cmd/troubleshoot
|
||||
|
||||
.PHONY: preflight
|
||||
preflight: generate fmt vet
|
||||
preflight:
|
||||
go build ${BUILDFLAGS} ${LDFLAGS} -o bin/preflight github.com/replicatedhq/troubleshoot/cmd/preflight
|
||||
|
||||
.PHONY: analyze
|
||||
analyze: generate fmt vet
|
||||
analyze:
|
||||
go build ${BUILDFLAGS} ${LDFLAGS} -o bin/analyze github.com/replicatedhq/troubleshoot/cmd/analyze
|
||||
|
||||
|
||||
.PHONY: collect
|
||||
collect: generate fmt vet
|
||||
go build ${BUILDFLAGS} ${LDFLAGS} -o bin/collect github.com/replicatedhq/troubleshoot/cmd/collect
|
||||
collect:
|
||||
go build ${BUILDFLAGS} ${LDFLAGS} -o bin/collect github.com/replicatedhq/troubleshoot/cmd/collect
|
||||
|
||||
.PHONY: fmt
|
||||
fmt:
|
||||
go fmt ./pkg/... ./cmd/...
|
||||
go fmt ${BUILDPATHS}
|
||||
|
||||
.PHONY: vet
|
||||
vet:
|
||||
go vet ${BUILDFLAGS} ./pkg/... ./cmd/...
|
||||
go vet ${BUILDFLAGS} ${BUILDPATHS}
|
||||
|
||||
.PHONY: generate
|
||||
generate: controller-gen client-gen
|
||||
$(CONTROLLER_GEN) \
|
||||
object:headerFile=./hack/boilerplate.go.txt paths=./pkg/apis/...
|
||||
$(CLIENT_GEN) \
|
||||
--output-base=./../../../ \
|
||||
--output-package=github.com/replicatedhq/troubleshoot/pkg/client \
|
||||
--clientset-name troubleshootclientset \
|
||||
--input-base github.com/replicatedhq/troubleshoot/pkg/apis \
|
||||
@@ -86,19 +107,31 @@ openapischema: controller-gen
|
||||
controller-gen crd +output:dir=./config/crds paths=./pkg/apis/troubleshoot/v1beta1
|
||||
controller-gen crd +output:dir=./config/crds paths=./pkg/apis/troubleshoot/v1beta2
|
||||
|
||||
check-schemas: generate schemas
|
||||
@if [ -n "$(shell git status --short)" ]; then \
|
||||
echo -e "\033[31mThe git repo is dirty :( Ensure all generated files are committed e.g CRD schema files\033[0;m"; \
|
||||
git status --short; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
.PHONY: schemas
|
||||
schemas: fmt vet openapischema
|
||||
go build ${LDFLAGS} -o bin/schemagen github.com/replicatedhq/troubleshoot/cmd/schemagen
|
||||
./bin/schemagen --output-dir ./schemas
|
||||
|
||||
.PHONY: docs
|
||||
docs: fmt vet
|
||||
go build ${LDFLAGS} -o bin/docsgen github.com/replicatedhq/troubleshoot/cmd/docsgen
|
||||
./bin/docsgen
|
||||
|
||||
controller-gen:
|
||||
go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.7.0
|
||||
go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.11.2
|
||||
CONTROLLER_GEN=$(shell which controller-gen)
|
||||
|
||||
.PHONY: client-gen
|
||||
client-gen:
|
||||
ifeq (, $(shell which client-gen))
|
||||
go install k8s.io/code-generator/cmd/client-gen@v0.22.2
|
||||
ifeq (, $(shell which client-gen 2>/dev/null))
|
||||
go install k8s.io/code-generator/cmd/client-gen@v0.26.1
|
||||
CLIENT_GEN=$(shell go env GOPATH)/bin/client-gen
|
||||
else
|
||||
CLIENT_GEN=$(shell which client-gen)
|
||||
@@ -150,7 +183,7 @@ generate-sbom: install-spdx-sbom-generator
|
||||
$(SPDX_GENERATOR) -o ./sbom/spdx
|
||||
|
||||
sbom/assets/troubleshoot-sbom.tgz: generate-sbom
|
||||
tar -czf sbom/assets/troubleshoot-sbom.tgz sbom/spdx/*.spdx
|
||||
tar -czf sbom/assets/troubleshoot-sbom.tgz sbom/spdx/*.spdx
|
||||
|
||||
sbom: sbom/assets/troubleshoot-sbom.tgz
|
||||
cosign sign-blob -key cosign.key sbom/assets/troubleshoot-sbom.tgz > sbom/assets/troubleshoot-sbom.tgz.sig
|
||||
@@ -169,3 +202,20 @@ longhorn:
|
||||
find pkg/longhorn -type f | xargs sed -i "s/github.com\/longhorn\/longhorn-manager\/types/github.com\/replicatedhq\/troubleshoot\/pkg\/longhorn\/types/g"
|
||||
find pkg/longhorn -type f | xargs sed -i "s/github.com\/longhorn\/longhorn-manager\/util/github.com\/replicatedhq\/troubleshoot\/pkg\/longhorn\/util/g"
|
||||
rm -rf longhorn-manager
|
||||
|
||||
.PHONY: scan
|
||||
scan:
|
||||
trivy fs \
|
||||
--security-checks vuln \
|
||||
--exit-code=1 \
|
||||
--severity="HIGH,CRITICAL" \
|
||||
--ignore-unfixed \
|
||||
./
|
||||
|
||||
.PHONY: lint
|
||||
lint: fmt vet
|
||||
golangci-lint run --new -c .golangci.yaml ${BUILDPATHS}
|
||||
|
||||
.PHONY: lint-and-fix
|
||||
lint-and-fix: fmt vet
|
||||
golangci-lint run --new --fix -c .golangci.yaml ${BUILDPATHS}
|
||||
|
||||
@@ -4,20 +4,24 @@ Replicated Troubleshoot is a framework for collecting, redacting, and analyzing
|
||||
|
||||
Troubleshoot provides two CLI tools as kubectl plugins (using [Krew](https://krew.dev)): `kubectl preflight` and `kubectl support-bundle`. Preflight provides pre-installation cluster conformance testing and validation (preflight checks) and support-bundle provides post-installation troubleshooting and diagnostics (support bundles).
|
||||
|
||||
To know more about troubleshoot, please visit: https://troubleshoot.sh/
|
||||
|
||||
## Preflight Checks
|
||||
Preflight checks are an easy-to-run set of conformance tests that can be written to verify that specific requirements in a cluster are met.
|
||||
|
||||
To run a sample preflight check from a sample application, install the preflight kubectl plugin:
|
||||
|
||||
```shell
|
||||
```
|
||||
curl https://krew.sh/preflight | bash
|
||||
```
|
||||
and run:
|
||||
|
||||
```shell
|
||||
and run, where https://preflight.replicated.com provides an **example** preflight spec:
|
||||
|
||||
```
|
||||
kubectl preflight https://preflight.replicated.com
|
||||
```
|
||||
|
||||
**NOTE** this is an example. Do **not** use to validate real scenarios.
|
||||
|
||||
For more details on creating the custom resource files that drive preflight checks, visit [creating preflight checks](https://troubleshoot.sh/docs/preflight/introduction/).
|
||||
|
||||
|
||||
@@ -26,29 +30,38 @@ A support bundle is an archive that's created in-cluster, by collecting logs and
|
||||
|
||||
To collect a sample support bundle, install the troubleshoot kubectl plugin:
|
||||
|
||||
```shell
|
||||
```
|
||||
curl https://krew.sh/support-bundle | bash
|
||||
```
|
||||
and run:
|
||||
|
||||
```shell
|
||||
and run, where https://support-bundle.replicated.com provides an **example** support bundle spec:
|
||||
|
||||
```
|
||||
kubectl support-bundle https://support-bundle.replicated.com
|
||||
```
|
||||
|
||||
**NOTE** this is an example. Do **not** use to validate real scenarios.
|
||||
|
||||
For more details on creating the custom resource files that drive support-bundle collection, visit [creating collectors](https://troubleshoot.sh/docs/collect/) and [creating analyzers](https://troubleshoot.sh/docs/analyze/).
|
||||
|
||||
And see our other tool [sbctl](https://github.com/replicatedhq/sbctl) that makes it easier to interact with support bundles using `kubectl` commands you already know
|
||||
|
||||
# Community
|
||||
|
||||
For questions about using Troubleshoot, there's a [Replicated Community](https://help.replicated.com/community) forum, and a [#app-troubleshoot channel in Kubernetes Slack](https://kubernetes.slack.com/channels/app-troubleshoot).
|
||||
For questions about using Troubleshoot, how to contribute and engaging with the project in any other way, please refer to the following resources and channels.
|
||||
|
||||
# Software Bill of Materials
|
||||
A signed SBOM that includes Troubleshoot dependencies is included in each release.
|
||||
- **troubleshoot-sbom.tgz** contains a software bill of materials for Troubleshoot.
|
||||
- [Replicated Community](https://help.replicated.com/community) forum
|
||||
- [#app-troubleshoot channel in Kubernetes Slack](https://kubernetes.slack.com/channels/app-troubleshoot)
|
||||
- [#Community meetings calendar](https://calendar.google.com/calendar/u/0?cid=Y19mMGx1aGhiZGtscGllOGo5dWpicXMwNnN1a0Bncm91cC5jYWxlbmRhci5nb29nbGUuY29t). This happen monthly but dates may change and would be kept upto date in the calendar.
|
||||
|
||||
# Software Bill of Materials
|
||||
A signed SBOM that includes Troubleshoot dependencies is included in each release.
|
||||
- **troubleshoot-sbom.tgz** contains a software bill of materials for Troubleshoot.
|
||||
- **troubleshoot-sbom.tgz.sig** is the digital signature for troubleshoot-sbom.tgz
|
||||
- **key.pub** is the public key from the key pair used to sign troubleshoot-sbom.tgz
|
||||
|
||||
The following example illustrates using [cosign](https://github.com/sigstore/cosign) to verify that **troubleshoot-sbom.tgz** has
|
||||
not been tampered with.
|
||||
```shell
|
||||
$ cosign verify-blob -key key.pub -signature troubleshoot-sbom.tgz.sig troubleshoot-sbom.tgz
|
||||
```
|
||||
$ cosign verify-blob --key key.pub --signature troubleshoot-sbom.tgz.sig troubleshoot-sbom.tgz
|
||||
Verified OK
|
||||
```
|
||||
```
|
||||
|
||||
+22
-3
@@ -4,10 +4,12 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/replicatedhq/troubleshoot/cmd/util"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/k8sutil"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/logger"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
func RootCmd() *cobra.Command {
|
||||
@@ -18,27 +20,44 @@ func RootCmd() *cobra.Command {
|
||||
Long: `Run a series of analyzers on a support bundle archive`,
|
||||
SilenceUsage: true,
|
||||
PreRun: func(cmd *cobra.Command, args []string) {
|
||||
viper.BindPFlags(cmd.Flags())
|
||||
v := viper.GetViper()
|
||||
v.BindPFlags(cmd.Flags())
|
||||
|
||||
logger.SetupLogger(v)
|
||||
|
||||
if err := util.StartProfiling(); err != nil {
|
||||
klog.Errorf("Failed to start profiling: %v", err)
|
||||
}
|
||||
},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
v := viper.GetViper()
|
||||
|
||||
logger.SetQuiet(v.GetBool("quiet"))
|
||||
|
||||
return runAnalyzers(v, args[0])
|
||||
},
|
||||
PostRun: func(cmd *cobra.Command, args []string) {
|
||||
if err := util.StopProfiling(); err != nil {
|
||||
klog.Errorf("Failed to stop profiling: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
cobra.OnInitialize(initConfig)
|
||||
|
||||
cmd.Flags().String("analyzers", "", "filename or url of the analyzers to use")
|
||||
cmd.Flags().Bool("debug", false, "enable debug logging")
|
||||
|
||||
viper.BindPFlags(cmd.Flags())
|
||||
|
||||
viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
|
||||
|
||||
// Initialize klog flags
|
||||
logger.InitKlogFlags(cmd)
|
||||
|
||||
k8sutil.AddFlags(cmd.Flags())
|
||||
|
||||
// CPU and memory profiling flags
|
||||
util.AddProfilingFlags(cmd)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
||||
+22
-2
@@ -4,10 +4,12 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/replicatedhq/troubleshoot/cmd/util"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/k8sutil"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/logger"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
func RootCmd() *cobra.Command {
|
||||
@@ -18,14 +20,25 @@ func RootCmd() *cobra.Command {
|
||||
Long: `Run a collector and output the results.`,
|
||||
SilenceUsage: true,
|
||||
PreRun: func(cmd *cobra.Command, args []string) {
|
||||
viper.BindPFlags(cmd.Flags())
|
||||
v := viper.GetViper()
|
||||
v.BindPFlags(cmd.Flags())
|
||||
|
||||
logger.SetupLogger(v)
|
||||
|
||||
if err := util.StartProfiling(); err != nil {
|
||||
klog.Errorf("Failed to start profiling: %v", err)
|
||||
}
|
||||
},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
v := viper.GetViper()
|
||||
|
||||
logger.SetQuiet(v.GetBool("quiet"))
|
||||
return runCollect(v, args[0])
|
||||
},
|
||||
PostRun: func(cmd *cobra.Command, args []string) {
|
||||
if err := util.StopProfiling(); err != nil {
|
||||
klog.Errorf("Failed to stop profiling: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
cobra.OnInitialize(initConfig)
|
||||
@@ -39,6 +52,7 @@ func RootCmd() *cobra.Command {
|
||||
cmd.Flags().String("collector-pull-policy", "", "the pull policy of the collector image")
|
||||
cmd.Flags().String("selector", "", "selector (label query) to filter remote collection nodes on.")
|
||||
cmd.Flags().Bool("collect-without-permissions", false, "always generate a support bundle, even if it some require additional permissions")
|
||||
cmd.Flags().Bool("debug", false, "enable debug logging")
|
||||
|
||||
// hidden in favor of the `insecure-skip-tls-verify` flag
|
||||
cmd.Flags().Bool("allow-insecure-connections", false, "when set, do not verify TLS certs when retrieving spec and reporting results")
|
||||
@@ -50,6 +64,12 @@ func RootCmd() *cobra.Command {
|
||||
|
||||
k8sutil.AddFlags(cmd.Flags())
|
||||
|
||||
// Initialize klog flags
|
||||
logger.InitKlogFlags(cmd)
|
||||
|
||||
// CPU and memory profiling flags
|
||||
util.AddProfilingFlags(cmd)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
||||
@@ -91,16 +91,15 @@ func runCollect(v *viper.Viper, arg string) error {
|
||||
troubleshootclientsetscheme.AddToScheme(scheme.Scheme)
|
||||
decode := scheme.Codecs.UniversalDeserializer().Decode
|
||||
|
||||
additionalRedactors := &troubleshootv1beta2.Redactor{}
|
||||
for idx, redactor := range v.GetStringSlice("redactors") {
|
||||
redactorObj, err := supportbundle.GetRedactorFromURI(redactor)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to get redactor spec %s, #%d", redactor, idx)
|
||||
}
|
||||
redactors, err := supportbundle.GetRedactorsFromURIs(v.GetStringSlice("redactors"))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to get redactors")
|
||||
}
|
||||
|
||||
if redactorObj != nil {
|
||||
additionalRedactors.Spec.Redactors = append(additionalRedactors.Spec.Redactors, redactorObj.Spec.Redactors...)
|
||||
}
|
||||
additionalRedactors := &troubleshootv1beta2.Redactor{
|
||||
Spec: troubleshootv1beta2.RedactorSpec{
|
||||
Redactors: redactors,
|
||||
},
|
||||
}
|
||||
|
||||
for i, additionalDoc := range multidocs {
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
preflightcli "github.com/replicatedhq/troubleshoot/cmd/preflight/cli"
|
||||
troubleshootcli "github.com/replicatedhq/troubleshoot/cmd/troubleshoot/cli"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/spf13/cobra/doc"
|
||||
)
|
||||
|
||||
func RootCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "docsgen",
|
||||
Short: "Generate markdown docs for the commands in this project",
|
||||
}
|
||||
preflight := preflightcli.RootCmd()
|
||||
troubleshoot := troubleshootcli.RootCmd()
|
||||
commands := []*cobra.Command{preflight, troubleshoot}
|
||||
|
||||
for _, command := range commands {
|
||||
err := doc.GenMarkdownTree(command, "./docs")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func InitAndExecute() {
|
||||
if err := RootCmd().Execute(); err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/replicatedhq/troubleshoot/cmd/docsgen/cli"
|
||||
_ "k8s.io/client-go/plugin/pkg/client/auth"
|
||||
)
|
||||
|
||||
func main() {
|
||||
cli.InitAndExecute()
|
||||
}
|
||||
+40
-13
@@ -1,12 +1,18 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/replicatedhq/troubleshoot/cmd/util"
|
||||
"github.com/replicatedhq/troubleshoot/internal/traces"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/k8sutil"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/logger"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/preflight"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
func RootCmd() *cobra.Command {
|
||||
@@ -18,31 +24,52 @@ func RootCmd() *cobra.Command {
|
||||
that a cluster meets the requirements to run an application.`,
|
||||
SilenceUsage: true,
|
||||
PreRun: func(cmd *cobra.Command, args []string) {
|
||||
viper.BindPFlags(cmd.Flags())
|
||||
v := viper.GetViper()
|
||||
v.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
|
||||
v.BindPFlags(cmd.Flags())
|
||||
|
||||
logger.SetupLogger(v)
|
||||
|
||||
if err := util.StartProfiling(); err != nil {
|
||||
klog.Errorf("Failed to start profiling: %v", err)
|
||||
}
|
||||
},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
v := viper.GetViper()
|
||||
return runPreflights(v, args[0])
|
||||
closer, err := traces.ConfigureTracing("preflight")
|
||||
if err != nil {
|
||||
// Do not fail running preflights if tracing fails
|
||||
klog.Errorf("Failed to initialize open tracing provider: %v", err)
|
||||
} else {
|
||||
defer closer()
|
||||
}
|
||||
|
||||
err = preflight.RunPreflights(v.GetBool("interactive"), v.GetString("output"), v.GetString("format"), args)
|
||||
if v.GetBool("debug") || v.IsSet("v") {
|
||||
fmt.Printf("\n%s", traces.GetExporterInstance().GetSummary())
|
||||
}
|
||||
return err
|
||||
},
|
||||
PostRun: func(cmd *cobra.Command, args []string) {
|
||||
if err := util.StopProfiling(); err != nil {
|
||||
klog.Errorf("Failed to stop profiling: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
cobra.OnInitialize(initConfig)
|
||||
|
||||
cmd.AddCommand(VersionCmd())
|
||||
|
||||
cmd.Flags().Bool("interactive", true, "interactive preflights")
|
||||
cmd.Flags().String("format", "human", "output format, one of human, json, yaml. only used when interactive is set to false")
|
||||
cmd.Flags().String("collector-image", "", "the full name of the collector image to use")
|
||||
cmd.Flags().String("collector-pullpolicy", "", "the pull policy of the collector image")
|
||||
cmd.Flags().Bool("collect-without-permissions", true, "always run preflight checks even if some require permissions that preflight does not have")
|
||||
cmd.Flags().String("selector", "", "selector (label query) to filter remote collection nodes on.")
|
||||
cmd.Flags().String("since-time", "", "force pod logs collectors to return logs after a specific date (RFC3339)")
|
||||
cmd.Flags().String("since", "", "force pod logs collectors to return logs newer than a relative duration like 5s, 2m, or 3h.")
|
||||
|
||||
viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
|
||||
preflight.AddFlags(cmd.PersistentFlags())
|
||||
|
||||
k8sutil.AddFlags(cmd.Flags())
|
||||
|
||||
// Initialize klog flags
|
||||
logger.InitKlogFlags(cmd)
|
||||
|
||||
// CPU and memory profiling flags
|
||||
util.AddProfilingFlags(cmd)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
analyzerunner "github.com/replicatedhq/troubleshoot/pkg/analyze"
|
||||
)
|
||||
|
||||
func showStdoutResults(format string, preflightName string, analyzeResults []*analyzerunner.AnalyzeResult) error {
|
||||
if format == "human" {
|
||||
return showStdoutResultsHuman(preflightName, analyzeResults)
|
||||
} else if format == "json" {
|
||||
return showStdoutResultsJSON(preflightName, analyzeResults)
|
||||
}
|
||||
|
||||
return errors.Errorf("unknown output format: %q", format)
|
||||
}
|
||||
|
||||
func showStdoutResultsHuman(preflightName string, analyzeResults []*analyzerunner.AnalyzeResult) error {
|
||||
fmt.Println("")
|
||||
var failed bool
|
||||
for _, analyzeResult := range analyzeResults {
|
||||
testResultfailed := outputResult(analyzeResult)
|
||||
if testResultfailed {
|
||||
failed = true
|
||||
}
|
||||
}
|
||||
if failed {
|
||||
fmt.Printf("--- FAIL %s\n", preflightName)
|
||||
fmt.Println("FAILED")
|
||||
} else {
|
||||
fmt.Printf("--- PASS %s\n", preflightName)
|
||||
fmt.Println("PASS")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func showStdoutResultsJSON(preflightName string, analyzeResults []*analyzerunner.AnalyzeResult) error {
|
||||
type ResultOutput struct {
|
||||
Title string `json:"title"`
|
||||
Message string `json:"message"`
|
||||
URI string `json:"uri,omitempty"`
|
||||
}
|
||||
type Output struct {
|
||||
Pass []ResultOutput `json:"pass,omitempty"`
|
||||
Warn []ResultOutput `json:"warn,omitempty"`
|
||||
Fail []ResultOutput `json:"fail,omitempty"`
|
||||
}
|
||||
|
||||
output := Output{
|
||||
Pass: []ResultOutput{},
|
||||
Warn: []ResultOutput{},
|
||||
Fail: []ResultOutput{},
|
||||
}
|
||||
|
||||
for _, analyzeResult := range analyzeResults {
|
||||
resultOutput := ResultOutput{
|
||||
Title: analyzeResult.Title,
|
||||
Message: analyzeResult.Message,
|
||||
URI: analyzeResult.URI,
|
||||
}
|
||||
|
||||
if analyzeResult.IsPass {
|
||||
output.Pass = append(output.Pass, resultOutput)
|
||||
} else if analyzeResult.IsWarn {
|
||||
output.Warn = append(output.Warn, resultOutput)
|
||||
} else if analyzeResult.IsFail {
|
||||
output.Fail = append(output.Fail, resultOutput)
|
||||
}
|
||||
}
|
||||
|
||||
b, err := json.MarshalIndent(output, "", " ")
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to marshal results")
|
||||
}
|
||||
|
||||
fmt.Printf("%s\n", b)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func outputResult(analyzeResult *analyzerunner.AnalyzeResult) bool {
|
||||
if analyzeResult.IsPass {
|
||||
fmt.Printf(" --- PASS %s\n", analyzeResult.Title)
|
||||
fmt.Printf(" --- %s\n", analyzeResult.Message)
|
||||
} else if analyzeResult.IsWarn {
|
||||
fmt.Printf(" --- WARN: %s\n", analyzeResult.Title)
|
||||
fmt.Printf(" --- %s\n", analyzeResult.Message)
|
||||
} else if analyzeResult.IsFail {
|
||||
fmt.Printf(" --- FAIL: %s\n", analyzeResult.Title)
|
||||
fmt.Printf(" --- %s\n", analyzeResult.Message)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
"github.com/replicatedhq/troubleshoot/cmd/util"
|
||||
analyzer "github.com/replicatedhq/troubleshoot/pkg/analyze"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/convert"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/logger"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"gopkg.in/yaml.v2"
|
||||
@@ -23,15 +22,11 @@ func Analyze() *cobra.Command {
|
||||
Short: "analyze a support bundle",
|
||||
Long: `Analyze a support bundle using the Analyzer definitions provided`,
|
||||
PreRun: func(cmd *cobra.Command, args []string) {
|
||||
viper.BindPFlag("bundle", cmd.Flags().Lookup("bundle"))
|
||||
viper.BindPFlag("output", cmd.Flags().Lookup("output"))
|
||||
viper.BindPFlag("quiet", cmd.Flags().Lookup("quiet"))
|
||||
viper.BindPFlags(cmd.Flags())
|
||||
},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
v := viper.GetViper()
|
||||
|
||||
logger.SetQuiet(v.GetBool("quiet"))
|
||||
|
||||
specPath := args[0]
|
||||
analyzerSpec, err := downloadAnalyzerSpec(specPath)
|
||||
if err != nil {
|
||||
@@ -77,8 +72,6 @@ func Analyze() *cobra.Command {
|
||||
cmd.Flags().MarkHidden("compatibility")
|
||||
cmd.Flags().Bool("quiet", false, "enable/disable error messaging and only show parseable output")
|
||||
|
||||
viper.BindPFlags(cmd.Flags())
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
||||
@@ -204,10 +204,11 @@ func drawDetails(analysisResult *analyzerunner.AnalyzeResult) {
|
||||
uri := widgets.NewParagraph()
|
||||
uri.Text = fmt.Sprintf("For more information: %s", analysisResult.URI)
|
||||
uri.Border = false
|
||||
height = estimateNumberOfLines(uri.Text, termWidth/2)
|
||||
// For long urls that lead to wrapping text, make the rectangle bigger by
|
||||
// increasing the calculated height by 2
|
||||
height = estimateNumberOfLines(uri.Text, termWidth/2) + 2
|
||||
uri.SetRect(termWidth/2, currentTop, termWidth, currentTop+height)
|
||||
ui.Render(uri)
|
||||
currentTop = currentTop + height + 1
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
analyzer "github.com/replicatedhq/troubleshoot/pkg/analyze"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/collect"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/supportbundle"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func Redact() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "redact [urls...]",
|
||||
Args: cobra.MinimumNArgs(1), // TODO
|
||||
Short: "Redact information from a generated support bundle archive",
|
||||
Long: `Redaction is the process of masking sensitive information from collected data in a support bundle.
|
||||
This is done using rules defined in the list of redactor manifests provided in the [urls...] command line
|
||||
argument. Default built in redactors will also be run, but these would have been run when the support
|
||||
bundle was generated. After redaction, the support bundle is archived once more. The resulting file will
|
||||
be stored in the current directory in the path provided by the --output flag.
|
||||
|
||||
The [urls...] argument is a list of either oci://.., http://.., https://.. or local paths to yaml files.
|
||||
|
||||
For more information on redactors visit https://troubleshoot.sh/docs/redact/
|
||||
`,
|
||||
PreRunE: func(cmd *cobra.Command, args []string) error {
|
||||
return viper.BindPFlags(cmd.Flags())
|
||||
},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
v := viper.GetViper()
|
||||
|
||||
// 1. Decode redactors from provided URLs
|
||||
redactors, err := supportbundle.GetRedactorsFromURIs(args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 2. Download the bundle and extract it
|
||||
tmpDir, bundleDir, err := analyzer.DownloadAndExtractSupportBundle(v.GetString("bundle"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
// 3. Represent bundle as a CollectorResult
|
||||
collectorResult, err := collect.CollectorResultFromBundle(bundleDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 4. Perform redaction on the bundle
|
||||
err = collect.RedactResult(bundleDir, collectorResult, redactors)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to redact support bundle")
|
||||
}
|
||||
|
||||
// 5. Compress the bundle once more after redacting
|
||||
output := v.GetString("output")
|
||||
if output == "" {
|
||||
output = fmt.Sprintf("redacted-support-bundle-%s.tar.gz", time.Now().Format("2006-01-02T15_04_05"))
|
||||
}
|
||||
err = collectorResult.ArchiveSupportBundle(bundleDir, output)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to create support bundle archive")
|
||||
}
|
||||
fmt.Println("Redacted support bundle:", output)
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().String("bundle", "", "file path of the support bundle archive to redact")
|
||||
cmd.MarkFlagRequired("bundle")
|
||||
cmd.Flags().BoolP("quiet", "q", false, "enable/disable error messaging and only show parseable output")
|
||||
cmd.Flags().StringP("output", "o", "", "file path of where to save the redacted support bundle archive (default \"redacted-support-bundle-YYYY-MM-DDTHH_MM_SS.tar.gz\")")
|
||||
|
||||
return cmd
|
||||
}
|
||||
@@ -1,58 +1,96 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
|
||||
"github.com/replicatedhq/troubleshoot/cmd/util"
|
||||
"github.com/replicatedhq/troubleshoot/internal/traces"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/k8sutil"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/logger"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
func RootCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "support-bundle [url]",
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
Use: "support-bundle [urls...]",
|
||||
Args: cobra.MinimumNArgs(0),
|
||||
Short: "Generate a support bundle",
|
||||
Long: `A support bundle is an archive of files, output, metrics and state
|
||||
from a server that can be used to assist when troubleshooting a Kubernetes cluster.`,
|
||||
SilenceUsage: true,
|
||||
PreRun: func(cmd *cobra.Command, args []string) {
|
||||
viper.BindPFlags(cmd.Flags())
|
||||
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||||
v := viper.GetViper()
|
||||
v.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
|
||||
v.BindPFlags(cmd.Flags())
|
||||
|
||||
logger.SetupLogger(v)
|
||||
|
||||
if err := util.StartProfiling(); err != nil {
|
||||
klog.Errorf("Failed to start profiling: %v", err)
|
||||
}
|
||||
},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
v := viper.GetViper()
|
||||
|
||||
logger.SetQuiet(v.GetBool("quiet"))
|
||||
return runTroubleshoot(v, args[0])
|
||||
closer, err := traces.ConfigureTracing("support-bundle")
|
||||
if err != nil {
|
||||
// Do not fail running support-bundle if tracing fails
|
||||
klog.Errorf("Failed to initialize open tracing provider: %v", err)
|
||||
} else {
|
||||
defer closer()
|
||||
}
|
||||
|
||||
err = runTroubleshoot(v, args)
|
||||
if v.GetBool("debug") || v.IsSet("v") {
|
||||
fmt.Printf("\n%s", traces.GetExporterInstance().GetSummary())
|
||||
}
|
||||
|
||||
return err
|
||||
},
|
||||
PersistentPostRun: func(cmd *cobra.Command, args []string) {
|
||||
if err := util.StopProfiling(); err != nil {
|
||||
klog.Errorf("Failed to stop profiling: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
cobra.OnInitialize(initConfig)
|
||||
|
||||
cmd.AddCommand(Analyze())
|
||||
cmd.AddCommand(Redact())
|
||||
cmd.AddCommand(VersionCmd())
|
||||
|
||||
cmd.Flags().StringSlice("redactors", []string{}, "names of the additional redactors to use")
|
||||
cmd.Flags().Bool("redact", true, "enable/disable default redactions")
|
||||
cmd.Flags().Bool("interactive", true, "enable/disable interactive mode")
|
||||
cmd.Flags().Bool("collect-without-permissions", true, "always generate a support bundle, even if it some require additional permissions")
|
||||
cmd.Flags().StringSliceP("selector", "l", []string{"troubleshoot.io/kind=support-bundle"}, "selector to filter on for loading additional support bundle specs found in secrets within the cluster")
|
||||
cmd.Flags().Bool("load-cluster-specs", false, "enable/disable loading additional troubleshoot specs found within the cluster. required when no specs are provided on the command line")
|
||||
cmd.Flags().String("since-time", "", "force pod logs collectors to return logs after a specific date (RFC3339)")
|
||||
cmd.Flags().String("since", "", "force pod logs collectors to return logs newer than a relative duration like 5s, 2m, or 3h.")
|
||||
cmd.Flags().StringP("output", "o", "", "specify the output file path for the support bundle")
|
||||
cmd.Flags().Bool("debug", false, "enable debug logging. This is equivalent to --v=0")
|
||||
|
||||
// hidden in favor of the `insecure-skip-tls-verify` flag
|
||||
cmd.Flags().Bool("allow-insecure-connections", false, "when set, do not verify TLS certs when retrieving spec and reporting results")
|
||||
cmd.Flags().MarkHidden("allow-insecure-connections")
|
||||
|
||||
viper.BindPFlags(cmd.Flags())
|
||||
|
||||
viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
|
||||
// `no-uri` references the `followURI` functionality where we can use an upstream spec when creating a support bundle
|
||||
// This flag makes sure we can also disable this and fall back to the default spec.
|
||||
cmd.Flags().Bool("no-uri", false, "When this flag is used, Troubleshoot does not attempt to retrieve the bundle referenced by the uri: field in the spec.`")
|
||||
|
||||
k8sutil.AddFlags(cmd.Flags())
|
||||
|
||||
// Initialize klog flags
|
||||
logger.InitKlogFlags(cmd)
|
||||
|
||||
// CPU and memory profiling flags
|
||||
util.AddProfilingFlags(cmd)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -66,24 +104,3 @@ func initConfig() {
|
||||
viper.SetEnvPrefix("TROUBLESHOOT")
|
||||
viper.AutomaticEnv()
|
||||
}
|
||||
|
||||
func ensureCollectorInList(list []*troubleshootv1beta2.Collect, collector troubleshootv1beta2.Collect) []*troubleshootv1beta2.Collect {
|
||||
for _, inList := range list {
|
||||
if collector.ClusterResources != nil && inList.ClusterResources != nil {
|
||||
return list
|
||||
}
|
||||
if collector.ClusterInfo != nil && inList.ClusterInfo != nil {
|
||||
return list
|
||||
}
|
||||
}
|
||||
|
||||
return append(list, &collector)
|
||||
}
|
||||
|
||||
func writeFile(filename string, contents []byte) error {
|
||||
if err := ioutil.WriteFile(filename, contents, 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
+237
-97
@@ -1,20 +1,20 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
cursor "github.com/ahmetalpbalkan/go-cursor"
|
||||
"github.com/fatih/color"
|
||||
"github.com/manifoldco/promptui"
|
||||
"github.com/mattn/go-isatty"
|
||||
"github.com/pkg/errors"
|
||||
analyzer "github.com/replicatedhq/troubleshoot/pkg/analyze"
|
||||
@@ -22,16 +22,25 @@ import (
|
||||
"github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/scheme"
|
||||
troubleshootclientsetscheme "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/scheme"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/convert"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/docrewrite"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/httputil"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/k8sutil"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/specs"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/supportbundle"
|
||||
"github.com/spf13/viper"
|
||||
spin "github.com/tj/go-spin"
|
||||
k8serrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
func runTroubleshoot(v *viper.Viper, arg string) error {
|
||||
func runTroubleshoot(v *viper.Viper, arg []string) error {
|
||||
if !v.GetBool("load-cluster-specs") && len(arg) < 1 {
|
||||
return errors.New("flag load-cluster-specs must be set if no specs are provided on the command line")
|
||||
}
|
||||
|
||||
interactive := v.GetBool("interactive") && isatty.IsTerminal(os.Stdout.Fd())
|
||||
|
||||
if interactive {
|
||||
@@ -68,81 +77,98 @@ func runTroubleshoot(v *viper.Viper, arg string) error {
|
||||
})
|
||||
}
|
||||
|
||||
collectorContent, err := supportbundle.LoadSupportBundleSpec(arg)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to load collector spec")
|
||||
}
|
||||
|
||||
multidocs := strings.Split(string(collectorContent), "\n---\n")
|
||||
|
||||
// we support both raw collector kinds and supportbundle kinds here
|
||||
supportBundle, err := supportbundle.ParseSupportBundleFromDoc([]byte(multidocs[0]))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to parse collector")
|
||||
}
|
||||
var mainBundle *troubleshootv1beta2.SupportBundle
|
||||
|
||||
troubleshootclientsetscheme.AddToScheme(scheme.Scheme)
|
||||
decode := scheme.Codecs.UniversalDeserializer().Decode
|
||||
|
||||
additionalRedactors := &troubleshootv1beta2.Redactor{}
|
||||
for idx, redactor := range v.GetStringSlice("redactors") {
|
||||
redactorObj, err := supportbundle.GetRedactorFromURI(redactor)
|
||||
|
||||
// Defining `v` below will render using `v` in reference to Viper unusable.
|
||||
// Therefore refactoring `v` to `val` will make sure we can still use it.
|
||||
for _, val := range arg {
|
||||
|
||||
collectorContent, err := supportbundle.LoadSupportBundleSpec(val)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to get redactor spec %s, #%d", redactor, idx)
|
||||
return errors.Wrap(err, "failed to load support bundle spec")
|
||||
}
|
||||
multidocs := strings.Split(string(collectorContent), "\n---\n")
|
||||
// Referencing `ParseSupportBundle with a secondary arg of `no-uri`
|
||||
// Will make sure we can enable or disable the use of the `Spec.uri` field for an upstream spec.
|
||||
// This change will not have an impact on KOTS' usage of `ParseSupportBundle`
|
||||
// As Kots uses `load.go` directly.
|
||||
supportBundle, err := supportbundle.ParseSupportBundle([]byte(multidocs[0]), !v.GetBool("no-uri"))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to parse support bundle spec")
|
||||
}
|
||||
|
||||
if redactorObj != nil {
|
||||
additionalRedactors.Spec.Redactors = append(additionalRedactors.Spec.Redactors, redactorObj.Spec.Redactors...)
|
||||
mainBundle = supportbundle.ConcatSpec(mainBundle, supportBundle)
|
||||
|
||||
parsedRedactors, err := supportbundle.ParseRedactorsFromDocs(multidocs)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to parse redactors from doc")
|
||||
}
|
||||
additionalRedactors.Spec.Redactors = append(additionalRedactors.Spec.Redactors, parsedRedactors...)
|
||||
}
|
||||
|
||||
for i, additionalDoc := range multidocs {
|
||||
if i == 0 {
|
||||
continue
|
||||
}
|
||||
additionalDoc, err := docrewrite.ConvertToV1Beta2([]byte(additionalDoc))
|
||||
if v.GetBool("load-cluster-specs") {
|
||||
sbFromCluster, redactorsFromCluster, err := loadClusterSpecs()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to convert to v1beta2")
|
||||
return err
|
||||
}
|
||||
obj, _, err := decode(additionalDoc, nil, nil)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to parse additional doc %d", i)
|
||||
if sbFromCluster == nil {
|
||||
return errors.New("no specs found in cluster")
|
||||
}
|
||||
multidocRedactors, ok := obj.(*troubleshootv1beta2.Redactor)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
additionalRedactors.Spec.Redactors = append(additionalRedactors.Spec.Redactors, multidocRedactors.Spec.Redactors...)
|
||||
mainBundle = supportbundle.ConcatSpec(mainBundle, sbFromCluster)
|
||||
additionalRedactors.Spec.Redactors = append(additionalRedactors.Spec.Redactors, redactorsFromCluster.Spec.Redactors...)
|
||||
}
|
||||
|
||||
var collectorCB func(chan interface{}, string)
|
||||
progressChan := make(chan interface{}) // non-zero buffer can result in missed messages
|
||||
finishedCh := make(chan bool, 1)
|
||||
isFinishedChClosed := false
|
||||
if mainBundle == nil {
|
||||
return errors.New("no support bundle specs provided to run")
|
||||
} else if mainBundle.Spec.Collectors == nil && mainBundle.Spec.HostCollectors == nil {
|
||||
return errors.New("no collectors specified in support bundle")
|
||||
}
|
||||
|
||||
redactors, err := supportbundle.GetRedactorsFromURIs(v.GetStringSlice("redactors"))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to get redactors")
|
||||
}
|
||||
additionalRedactors.Spec.Redactors = append(additionalRedactors.Spec.Redactors, redactors...)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
collectorCB := func(c chan interface{}, msg string) { c <- msg }
|
||||
progressChan := make(chan interface{})
|
||||
isProgressChanClosed := false
|
||||
defer func() {
|
||||
if !isProgressChanClosed {
|
||||
close(progressChan)
|
||||
}
|
||||
wg.Wait()
|
||||
}()
|
||||
|
||||
if !interactive {
|
||||
// TODO (dans): custom warning handler to capture warning in `analysisOutput`
|
||||
restConfig.WarningHandler = rest.NoWarnings{}
|
||||
collectorCB = func(ch chan interface{}, name string) {
|
||||
return
|
||||
}
|
||||
|
||||
// TODO (dans): maybe log to file
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case _ = <-progressChan:
|
||||
// do nothing
|
||||
}
|
||||
defer wg.Done()
|
||||
for msg := range progressChan {
|
||||
klog.Infof("Collecting support bundle: %v", msg)
|
||||
}
|
||||
}()
|
||||
} else {
|
||||
s := spin.New()
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
currentDir := ""
|
||||
for {
|
||||
select {
|
||||
case msg := <-progressChan:
|
||||
case msg, ok := <-progressChan:
|
||||
if !ok {
|
||||
fmt.Printf("\r%s\r", cursor.ClearEntireLine())
|
||||
return
|
||||
}
|
||||
switch msg := msg.(type) {
|
||||
case error:
|
||||
c := color.New(color.FgHiRed)
|
||||
@@ -150,9 +176,6 @@ func runTroubleshoot(v *viper.Viper, arg string) error {
|
||||
case string:
|
||||
currentDir = filepath.Base(msg)
|
||||
}
|
||||
case <-finishedCh:
|
||||
fmt.Printf("\r%s\r", cursor.ClearEntireLine())
|
||||
return
|
||||
case <-time.After(time.Millisecond * 100):
|
||||
if currentDir == "" {
|
||||
fmt.Printf("\r%s \033[36mCollecting support bundle\033[m %s", cursor.ClearEntireLine(), s.Next())
|
||||
@@ -162,16 +185,6 @@ func runTroubleshoot(v *viper.Viper, arg string) error {
|
||||
}
|
||||
}
|
||||
}()
|
||||
defer func() {
|
||||
if !isFinishedChClosed {
|
||||
close(finishedCh)
|
||||
}
|
||||
}()
|
||||
|
||||
collectorCB = func(c chan interface{}, msg string) {
|
||||
c <- fmt.Sprintf("%s", msg)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
createOpts := supportbundle.SupportBundleCreateOpts{
|
||||
@@ -181,6 +194,7 @@ func runTroubleshoot(v *viper.Viper, arg string) error {
|
||||
Namespace: v.GetString("namespace"),
|
||||
ProgressChan: progressChan,
|
||||
SinceTime: sinceTime,
|
||||
OutputPath: v.GetString("output"),
|
||||
Redact: v.GetBool("redact"),
|
||||
FromCLI: true,
|
||||
}
|
||||
@@ -192,16 +206,17 @@ func runTroubleshoot(v *viper.Viper, arg string) error {
|
||||
c.Println(fmt.Sprintf("\r%s\r", cursor.ClearEntireLine()))
|
||||
}
|
||||
|
||||
response, err := supportbundle.CollectSupportBundleFromSpec(&supportBundle.Spec, additionalRedactors, createOpts)
|
||||
response, err := supportbundle.CollectSupportBundleFromSpec(&mainBundle.Spec, additionalRedactors, createOpts)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to run collect and analyze process")
|
||||
}
|
||||
|
||||
close(progressChan) // this removes the spinner in interactive mode
|
||||
isProgressChanClosed = true
|
||||
|
||||
if len(response.AnalyzerResults) > 0 {
|
||||
if interactive {
|
||||
close(finishedCh) // this removes the spinner
|
||||
isFinishedChClosed = true
|
||||
|
||||
if err := showInteractiveResults(supportBundle.Name, response.AnalyzerResults); err != nil {
|
||||
if err := showInteractiveResults(mainBundle.Name, response.AnalyzerResults); err != nil {
|
||||
interactive = false
|
||||
}
|
||||
} else {
|
||||
@@ -210,7 +225,7 @@ func runTroubleshoot(v *viper.Viper, arg string) error {
|
||||
}
|
||||
|
||||
if !response.FileUploaded {
|
||||
if appName := supportBundle.Labels["applicationName"]; appName != "" {
|
||||
if appName := mainBundle.Labels["applicationName"]; appName != "" {
|
||||
f := `A support bundle for %s has been created in this directory
|
||||
named %s. Please upload it on the Troubleshoot page of
|
||||
the %s Admin Console to begin analysis.`
|
||||
@@ -228,7 +243,7 @@ the %s Admin Console to begin analysis.`
|
||||
return nil
|
||||
}
|
||||
|
||||
fmt.Printf("%s\n", response.ArchivePath)
|
||||
fmt.Printf("\n%s\n", response.ArchivePath)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -244,12 +259,160 @@ the %s Admin Console to begin analysis.`
|
||||
return nil
|
||||
}
|
||||
|
||||
func getExpectedContentType(uploadURL string) string {
|
||||
parsedURL, err := url.Parse(uploadURL)
|
||||
// loadClusterSpecs loads the support bundle and redactor specs from the cluster
|
||||
// based on troubleshoot.io/kind=support-bundle label selector. We search for secrets
|
||||
// and configmaps with the label selector and parse the data as a support bundle. If the
|
||||
// user does not have sufficient permissions to list & read secrets and configmaps from
|
||||
// all namespaces, we will fallback to trying each namespace individually, and eventually
|
||||
// default to the configured kubeconfig namespace.
|
||||
func loadClusterSpecs() (*troubleshootv1beta2.SupportBundle, *troubleshootv1beta2.Redactor, error) {
|
||||
var parsedBundle *troubleshootv1beta2.SupportBundle
|
||||
redactors := &troubleshootv1beta2.Redactor{}
|
||||
|
||||
v := viper.GetViper() // It's singleton, so we can use it anywhere
|
||||
|
||||
klog.Info("Discover troubleshoot specs from cluster")
|
||||
|
||||
labelSelector := strings.Join(v.GetStringSlice("selector"), ",")
|
||||
|
||||
parsedSelector, err := labels.Parse(labelSelector)
|
||||
if err != nil {
|
||||
return ""
|
||||
return nil, nil, errors.Wrap(err, "unable to parse selector")
|
||||
}
|
||||
return parsedURL.Query().Get("Content-Type")
|
||||
|
||||
config, err := k8sutil.GetRESTConfig()
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(err, "failed to convert kube flags to rest config")
|
||||
}
|
||||
|
||||
client, err := kubernetes.NewForConfig(config)
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(err, "failed to convert create k8s client")
|
||||
}
|
||||
|
||||
// List of namespaces we want to search for secrets and configmaps with support bundle specs
|
||||
namespaces := []string{}
|
||||
ctx := context.Background()
|
||||
|
||||
if v.GetString("namespace") != "" {
|
||||
// Just progress with the namespace provided
|
||||
namespaces = []string{v.GetString("namespace")}
|
||||
} else {
|
||||
// Check if I can read secrets and configmaps in all namespaces
|
||||
ican, err := k8sutil.CanIListAndGetAllSecretsAndConfigMaps(ctx, client)
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(err, "failed to check if I can read secrets and configmaps")
|
||||
}
|
||||
klog.V(1).Infof("Can I read any secrets and configmaps: %v", ican)
|
||||
|
||||
if ican {
|
||||
// I can read secrets and configmaps in all namespaces
|
||||
// No need to iterate over all namespaces
|
||||
namespaces = []string{""}
|
||||
} else {
|
||||
// Get list of all namespaces and try to find specs from each namespace
|
||||
nsList, err := client.CoreV1().Namespaces().List(ctx, metav1.ListOptions{})
|
||||
if err != nil {
|
||||
if k8serrors.IsForbidden(err) {
|
||||
kubeconfig := k8sutil.GetKubeconfig()
|
||||
ns, _, err := kubeconfig.Namespace()
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(err, "failed to get namespace from kubeconfig")
|
||||
}
|
||||
// If we are not allowed to list namespaces, just use the default namespace
|
||||
// configured in the kubeconfig
|
||||
namespaces = []string{ns}
|
||||
} else {
|
||||
return nil, nil, errors.Wrap(err, "failed to list namespaces")
|
||||
}
|
||||
}
|
||||
|
||||
for _, ns := range nsList.Items {
|
||||
namespaces = append(namespaces, ns.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var bundlesFromCluster []string
|
||||
|
||||
// Search cluster for support bundle specs
|
||||
klog.V(1).Infof("Search support bundle specs from [%q] namespaces using %q selector", strings.Join(namespaces, ", "), parsedSelector.String())
|
||||
for _, ns := range namespaces {
|
||||
bundlesFromSecrets, err := specs.LoadFromSecretMatchingLabel(client, parsedSelector.String(), ns, specs.SupportBundleKey)
|
||||
if err != nil {
|
||||
if !k8serrors.IsForbidden(err) {
|
||||
klog.Errorf("failed to load support bundle spec from secrets: %s", err)
|
||||
} else {
|
||||
klog.Warningf("Reading secrets from %q namespace forbidden", ns)
|
||||
}
|
||||
}
|
||||
bundlesFromCluster = append(bundlesFromCluster, bundlesFromSecrets...)
|
||||
|
||||
bundlesFromConfigMaps, err := specs.LoadFromConfigMapMatchingLabel(client, parsedSelector.String(), ns, specs.SupportBundleKey)
|
||||
if err != nil {
|
||||
if !k8serrors.IsForbidden(err) {
|
||||
klog.Errorf("failed to load support bundle spec from configmap: %s", err)
|
||||
} else {
|
||||
klog.Warningf("Reading configmaps from %q namespace forbidden", ns)
|
||||
}
|
||||
}
|
||||
bundlesFromCluster = append(bundlesFromCluster, bundlesFromConfigMaps...)
|
||||
}
|
||||
|
||||
for _, bundle := range bundlesFromCluster {
|
||||
multidocs := strings.Split(string(bundle), "\n---\n")
|
||||
parsedBundle, err = supportbundle.ParseSupportBundleFromDoc([]byte(multidocs[0]))
|
||||
if err != nil {
|
||||
klog.Errorf("failed to parse support bundle spec: %s", err)
|
||||
continue
|
||||
}
|
||||
|
||||
parsedRedactors, err := supportbundle.ParseRedactorsFromDocs(multidocs)
|
||||
if err != nil {
|
||||
klog.Errorf("failed to parse redactors from doc: %s", err)
|
||||
continue
|
||||
}
|
||||
|
||||
redactors.Spec.Redactors = append(redactors.Spec.Redactors, parsedRedactors...)
|
||||
}
|
||||
|
||||
var redactorsFromCluster []string
|
||||
|
||||
// Search cluster for redactor specs
|
||||
klog.V(1).Infof("Search redactor specs from [%q] namespaces using %q selector", strings.Join(namespaces, ", "), parsedSelector.String())
|
||||
for _, ns := range namespaces {
|
||||
redactorsFromSecrets, err := specs.LoadFromSecretMatchingLabel(client, parsedSelector.String(), ns, specs.RedactorKey)
|
||||
if err != nil {
|
||||
if !k8serrors.IsForbidden(err) {
|
||||
klog.Errorf("failed to load support bundle spec from secrets: %s", err)
|
||||
} else {
|
||||
klog.Warningf("Reading secrets from %q namespace forbidden", ns)
|
||||
}
|
||||
}
|
||||
redactorsFromCluster = append(redactorsFromCluster, redactorsFromSecrets...)
|
||||
|
||||
redactorsFromConfigMaps, err := specs.LoadFromConfigMapMatchingLabel(client, parsedSelector.String(), ns, specs.RedactorKey)
|
||||
if err != nil {
|
||||
if !k8serrors.IsForbidden(err) {
|
||||
klog.Errorf("failed to load support bundle spec from configmap: %s", err)
|
||||
} else {
|
||||
klog.Warningf("Reading configmaps from %q namespace forbidden", ns)
|
||||
}
|
||||
}
|
||||
redactorsFromCluster = append(redactorsFromCluster, redactorsFromConfigMaps...)
|
||||
}
|
||||
|
||||
for _, redactor := range redactorsFromCluster {
|
||||
multidocs := strings.Split(string(redactor), "\n---\n")
|
||||
parsedRedactors, err := supportbundle.ParseRedactorsFromDocs(multidocs)
|
||||
if err != nil {
|
||||
klog.Errorf("failed to parse redactors from doc: %s", err)
|
||||
}
|
||||
|
||||
redactors.Spec.Redactors = append(redactors.Spec.Redactors, parsedRedactors...)
|
||||
}
|
||||
|
||||
return parsedBundle, redactors, nil
|
||||
}
|
||||
|
||||
func parseTimeFlags(v *viper.Viper) (*time.Time, error) {
|
||||
@@ -277,29 +440,6 @@ func parseTimeFlags(v *viper.Viper) (*time.Time, error) {
|
||||
return &sinceTime, nil
|
||||
}
|
||||
|
||||
func shouldRetryRequest(err error) bool {
|
||||
if strings.Contains(err.Error(), "x509") && canTryInsecure() {
|
||||
httputil.AddTransport(&http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
})
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func canTryInsecure() bool {
|
||||
if !isatty.IsTerminal(os.Stdout.Fd()) {
|
||||
return false
|
||||
}
|
||||
prompt := promptui.Prompt{
|
||||
Label: "Connection appears to be insecure. Would you like to attempt to create a support bundle anyway?",
|
||||
IsConfirm: true,
|
||||
}
|
||||
|
||||
_, err := prompt.Run()
|
||||
return err == nil
|
||||
}
|
||||
|
||||
type analysisOutput struct {
|
||||
Analysis []*analyzer.AnalyzeResult
|
||||
ArchivePath string
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func findFileName(basename, extension string) (string, error) {
|
||||
n := 1
|
||||
name := basename
|
||||
for {
|
||||
filename := name + "." + extension
|
||||
if _, err := os.Stat(filename); os.IsNotExist(err) {
|
||||
return filename, nil
|
||||
} else if err != nil {
|
||||
return "", errors.Wrap(err, "check file exists")
|
||||
}
|
||||
|
||||
name = fmt.Sprintf("%s (%d)", basename, n)
|
||||
n = n + 1
|
||||
}
|
||||
}
|
||||
@@ -3,13 +3,8 @@ package cli
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
|
||||
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/version"
|
||||
"github.com/spf13/cobra"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
func VersionCmd() *cobra.Command {
|
||||
@@ -25,27 +20,3 @@ func VersionCmd() *cobra.Command {
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
const VersionFilename = "version.yaml"
|
||||
|
||||
func writeVersionFile(path string) error {
|
||||
version := troubleshootv1beta2.SupportBundleVersion{
|
||||
ApiVersion: "troubleshoot.sh/v1beta2",
|
||||
Kind: "SupportBundle",
|
||||
Spec: troubleshootv1beta2.SupportBundleVersionSpec{
|
||||
VersionNumber: version.Version(),
|
||||
},
|
||||
}
|
||||
b, err := yaml.Marshal(version)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
filename := filepath.Join(path, VersionFilename)
|
||||
err = ioutil.WriteFile(filename, b, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"runtime/pprof"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
var (
|
||||
cpuProfileFile *os.File
|
||||
)
|
||||
|
||||
// StartProfiling starts profiling CPU and memory usage if either --cpuprofile or
|
||||
// --memprofile flags were set and bound to viper configurations respectively.
|
||||
func StartProfiling() error {
|
||||
v := viper.GetViper()
|
||||
if v.GetString("cpuprofile") != "" {
|
||||
var err error
|
||||
cpuProfileFile, err = os.Create(v.GetString("cpuprofile"))
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not create CPU profile: %w", err)
|
||||
}
|
||||
if err := pprof.StartCPUProfile(cpuProfileFile); err != nil {
|
||||
cpuProfileFile.Close()
|
||||
cpuProfileFile = nil
|
||||
return fmt.Errorf("could not start CPU profile: %w", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// StopProfiling stops profiling CPU and memory usage and writes the results to
|
||||
// the files specified by --cpuprofile and --memprofile flags respectively.
|
||||
func StopProfiling() error {
|
||||
v := viper.GetViper()
|
||||
errs := []string{}
|
||||
|
||||
// Stop CPU profiling if it was started
|
||||
if cpuProfileFile != nil {
|
||||
pprof.StopCPUProfile()
|
||||
err := cpuProfileFile.Close()
|
||||
if err != nil {
|
||||
errs = append(errs, err.Error())
|
||||
}
|
||||
cpuProfileFile = nil
|
||||
}
|
||||
|
||||
if v.GetString("memprofile") != "" {
|
||||
f, err := os.Create(v.GetString("memprofile"))
|
||||
if err != nil {
|
||||
errs = append(errs, err.Error())
|
||||
goto BREAK_FROM_MEMPROFILE_IF
|
||||
}
|
||||
runtime.GC() // get up-to-date statistics
|
||||
if err := pprof.WriteHeapProfile(f); err != nil {
|
||||
errs = append(errs, err.Error())
|
||||
goto BREAK_FROM_MEMPROFILE_IF
|
||||
}
|
||||
err = f.Close()
|
||||
if err != nil {
|
||||
errs = append(errs, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
BREAK_FROM_MEMPROFILE_IF:
|
||||
if len(errs) > 0 {
|
||||
return fmt.Errorf("errors while stopping profiling: [%s]", strings.Join(errs, ", "))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddProfilingFlags adds the --cpuprofile and --memprofile flags to the given command.
|
||||
func AddProfilingFlags(cmd *cobra.Command) {
|
||||
// Persistent flags to make available to subcommands
|
||||
cmd.PersistentFlags().String("cpuprofile", "", "File path to write cpu profiling data")
|
||||
cmd.PersistentFlags().String("memprofile", "", "File path to write memory profiling data")
|
||||
}
|
||||
+4
-1
@@ -4,6 +4,9 @@ import (
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/text/cases"
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
func HomeDir() string {
|
||||
@@ -23,7 +26,7 @@ func IsURL(str string) bool {
|
||||
}
|
||||
|
||||
func AppName(name string) string {
|
||||
words := strings.Split(strings.Title(strings.Replace(name, "-", " ", -1)), " ")
|
||||
words := strings.Split(cases.Title(language.English).String(strings.ReplaceAll(name, "-", " ")), " ")
|
||||
casedWords := []string{}
|
||||
for i, word := range words {
|
||||
if strings.ToLower(word) == "ai" {
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
apiVersion: troubleshoot.sh/v1beta2
|
||||
kind: RemoteCollector
|
||||
metadata:
|
||||
name: modules
|
||||
spec:
|
||||
collectors:
|
||||
- cpu: {}
|
||||
- memory: {}
|
||||
# - kernelModules: {}
|
||||
@@ -1,10 +1,9 @@
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.7.0
|
||||
controller-gen.kubebuilder.io/version: v0.11.2
|
||||
creationTimestamp: null
|
||||
name: analyzers.troubleshoot.replicated.com
|
||||
spec:
|
||||
@@ -687,7 +686,6 @@ spec:
|
||||
type: string
|
||||
required:
|
||||
- outcomes
|
||||
- storageClassName
|
||||
type: object
|
||||
textAnalyze:
|
||||
properties:
|
||||
@@ -747,9 +745,3 @@ spec:
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.7.0
|
||||
controller-gen.kubebuilder.io/version: v0.11.2
|
||||
creationTimestamp: null
|
||||
name: collectors.troubleshoot.replicated.com
|
||||
spec:
|
||||
@@ -329,9 +328,3 @@ spec:
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.7.0
|
||||
controller-gen.kubebuilder.io/version: v0.11.2
|
||||
creationTimestamp: null
|
||||
name: preflights.troubleshoot.replicated.com
|
||||
spec:
|
||||
@@ -687,7 +686,6 @@ spec:
|
||||
type: string
|
||||
required:
|
||||
- outcomes
|
||||
- storageClassName
|
||||
type: object
|
||||
textAnalyze:
|
||||
properties:
|
||||
@@ -1004,9 +1002,3 @@ spec:
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.7.0
|
||||
controller-gen.kubebuilder.io/version: v0.11.2
|
||||
creationTimestamp: null
|
||||
name: redactors.troubleshoot.replicated.com
|
||||
spec:
|
||||
@@ -79,9 +78,3 @@ spec:
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.7.0
|
||||
controller-gen.kubebuilder.io/version: v0.11.2
|
||||
creationTimestamp: null
|
||||
name: supportbundles.troubleshoot.replicated.com
|
||||
spec:
|
||||
@@ -718,7 +717,6 @@ spec:
|
||||
type: string
|
||||
required:
|
||||
- outcomes
|
||||
- storageClassName
|
||||
type: object
|
||||
textAnalyze:
|
||||
properties:
|
||||
@@ -1033,9 +1031,3 @@ spec:
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,9 @@
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.7.0
|
||||
controller-gen.kubebuilder.io/version: v0.11.2
|
||||
creationTimestamp: null
|
||||
name: hostcollectors.troubleshoot.sh
|
||||
spec:
|
||||
@@ -41,8 +40,14 @@ spec:
|
||||
properties:
|
||||
blockDevices:
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
checkName:
|
||||
type: string
|
||||
collectorName:
|
||||
type: string
|
||||
exclude:
|
||||
type: BoolString
|
||||
includeUnmountedPartitions:
|
||||
@@ -82,6 +87,8 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
strict:
|
||||
type: BoolString
|
||||
required:
|
||||
- includeUnmountedPartitions
|
||||
- minimumAcceptableSize
|
||||
@@ -89,6 +96,10 @@ spec:
|
||||
type: object
|
||||
certificate:
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
checkName:
|
||||
type: string
|
||||
collectorName:
|
||||
@@ -127,13 +138,21 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
strict:
|
||||
type: BoolString
|
||||
required:
|
||||
- outcomes
|
||||
type: object
|
||||
cpu:
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
checkName:
|
||||
type: string
|
||||
collectorName:
|
||||
type: string
|
||||
exclude:
|
||||
type: BoolString
|
||||
outcomes:
|
||||
@@ -168,11 +187,17 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
strict:
|
||||
type: BoolString
|
||||
required:
|
||||
- outcomes
|
||||
type: object
|
||||
diskUsage:
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
checkName:
|
||||
type: string
|
||||
collectorName:
|
||||
@@ -211,11 +236,17 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
strict:
|
||||
type: BoolString
|
||||
required:
|
||||
- outcomes
|
||||
type: object
|
||||
filesystemPerformance:
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
checkName:
|
||||
type: string
|
||||
collectorName:
|
||||
@@ -254,13 +285,21 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
strict:
|
||||
type: BoolString
|
||||
required:
|
||||
- outcomes
|
||||
type: object
|
||||
hostOS:
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
checkName:
|
||||
type: string
|
||||
collectorName:
|
||||
type: string
|
||||
exclude:
|
||||
type: BoolString
|
||||
outcomes:
|
||||
@@ -295,13 +334,21 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
strict:
|
||||
type: BoolString
|
||||
required:
|
||||
- outcomes
|
||||
type: object
|
||||
hostServices:
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
checkName:
|
||||
type: string
|
||||
collectorName:
|
||||
type: string
|
||||
exclude:
|
||||
type: BoolString
|
||||
outcomes:
|
||||
@@ -336,11 +383,17 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
strict:
|
||||
type: BoolString
|
||||
required:
|
||||
- outcomes
|
||||
type: object
|
||||
http:
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
checkName:
|
||||
type: string
|
||||
collectorName:
|
||||
@@ -379,11 +432,17 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
strict:
|
||||
type: BoolString
|
||||
required:
|
||||
- outcomes
|
||||
type: object
|
||||
httpLoadBalancer:
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
checkName:
|
||||
type: string
|
||||
collectorName:
|
||||
@@ -422,13 +481,21 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
strict:
|
||||
type: BoolString
|
||||
required:
|
||||
- outcomes
|
||||
type: object
|
||||
ipv4Interfaces:
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
checkName:
|
||||
type: string
|
||||
collectorName:
|
||||
type: string
|
||||
exclude:
|
||||
type: BoolString
|
||||
outcomes:
|
||||
@@ -463,13 +530,21 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
strict:
|
||||
type: BoolString
|
||||
required:
|
||||
- outcomes
|
||||
type: object
|
||||
kernelModules:
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
checkName:
|
||||
type: string
|
||||
collectorName:
|
||||
type: string
|
||||
exclude:
|
||||
type: BoolString
|
||||
outcomes:
|
||||
@@ -504,13 +579,21 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
strict:
|
||||
type: BoolString
|
||||
required:
|
||||
- outcomes
|
||||
type: object
|
||||
memory:
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
checkName:
|
||||
type: string
|
||||
collectorName:
|
||||
type: string
|
||||
exclude:
|
||||
type: BoolString
|
||||
outcomes:
|
||||
@@ -545,11 +628,115 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
strict:
|
||||
type: BoolString
|
||||
required:
|
||||
- outcomes
|
||||
type: object
|
||||
subnetAvailable:
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
checkName:
|
||||
type: string
|
||||
collectorName:
|
||||
type: string
|
||||
exclude:
|
||||
type: BoolString
|
||||
outcomes:
|
||||
items:
|
||||
properties:
|
||||
fail:
|
||||
properties:
|
||||
message:
|
||||
type: string
|
||||
uri:
|
||||
type: string
|
||||
when:
|
||||
type: string
|
||||
type: object
|
||||
pass:
|
||||
properties:
|
||||
message:
|
||||
type: string
|
||||
uri:
|
||||
type: string
|
||||
when:
|
||||
type: string
|
||||
type: object
|
||||
warn:
|
||||
properties:
|
||||
message:
|
||||
type: string
|
||||
uri:
|
||||
type: string
|
||||
when:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
strict:
|
||||
type: BoolString
|
||||
required:
|
||||
- outcomes
|
||||
type: object
|
||||
systemPackages:
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
checkName:
|
||||
type: string
|
||||
collectorName:
|
||||
type: string
|
||||
exclude:
|
||||
type: BoolString
|
||||
outcomes:
|
||||
items:
|
||||
properties:
|
||||
fail:
|
||||
properties:
|
||||
message:
|
||||
type: string
|
||||
uri:
|
||||
type: string
|
||||
when:
|
||||
type: string
|
||||
type: object
|
||||
pass:
|
||||
properties:
|
||||
message:
|
||||
type: string
|
||||
uri:
|
||||
type: string
|
||||
when:
|
||||
type: string
|
||||
type: object
|
||||
warn:
|
||||
properties:
|
||||
message:
|
||||
type: string
|
||||
uri:
|
||||
type: string
|
||||
when:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
strict:
|
||||
type: BoolString
|
||||
required:
|
||||
- outcomes
|
||||
type: object
|
||||
tcpConnect:
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
checkName:
|
||||
type: string
|
||||
collectorName:
|
||||
@@ -588,11 +775,17 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
strict:
|
||||
type: BoolString
|
||||
required:
|
||||
- outcomes
|
||||
type: object
|
||||
tcpLoadBalancer:
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
checkName:
|
||||
type: string
|
||||
collectorName:
|
||||
@@ -631,11 +824,17 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
strict:
|
||||
type: BoolString
|
||||
required:
|
||||
- outcomes
|
||||
type: object
|
||||
tcpPortStatus:
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
checkName:
|
||||
type: string
|
||||
collectorName:
|
||||
@@ -674,13 +873,21 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
strict:
|
||||
type: BoolString
|
||||
required:
|
||||
- outcomes
|
||||
type: object
|
||||
time:
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
checkName:
|
||||
type: string
|
||||
collectorName:
|
||||
type: string
|
||||
exclude:
|
||||
type: BoolString
|
||||
outcomes:
|
||||
@@ -715,6 +922,57 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
strict:
|
||||
type: BoolString
|
||||
required:
|
||||
- outcomes
|
||||
type: object
|
||||
udpPortStatus:
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
checkName:
|
||||
type: string
|
||||
collectorName:
|
||||
type: string
|
||||
exclude:
|
||||
type: BoolString
|
||||
outcomes:
|
||||
items:
|
||||
properties:
|
||||
fail:
|
||||
properties:
|
||||
message:
|
||||
type: string
|
||||
uri:
|
||||
type: string
|
||||
when:
|
||||
type: string
|
||||
type: object
|
||||
pass:
|
||||
properties:
|
||||
message:
|
||||
type: string
|
||||
uri:
|
||||
type: string
|
||||
when:
|
||||
type: string
|
||||
type: object
|
||||
warn:
|
||||
properties:
|
||||
message:
|
||||
type: string
|
||||
uri:
|
||||
type: string
|
||||
when:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
strict:
|
||||
type: BoolString
|
||||
required:
|
||||
- outcomes
|
||||
type: object
|
||||
@@ -951,6 +1209,127 @@ spec:
|
||||
exclude:
|
||||
type: BoolString
|
||||
type: object
|
||||
run:
|
||||
properties:
|
||||
args:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
collectorName:
|
||||
type: string
|
||||
command:
|
||||
type: string
|
||||
exclude:
|
||||
type: BoolString
|
||||
required:
|
||||
- args
|
||||
- command
|
||||
type: object
|
||||
subnetAvailable:
|
||||
properties:
|
||||
CIDRRangeAlloc:
|
||||
type: string
|
||||
collectorName:
|
||||
type: string
|
||||
desiredCIDR:
|
||||
type: integer
|
||||
exclude:
|
||||
type: BoolString
|
||||
required:
|
||||
- CIDRRangeAlloc
|
||||
- desiredCIDR
|
||||
type: object
|
||||
systemPackages:
|
||||
properties:
|
||||
amzn:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
amzn2:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
centos:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
centos7:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
centos8:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
centos9:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
collectorName:
|
||||
type: string
|
||||
exclude:
|
||||
type: BoolString
|
||||
ol:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
ol7:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
ol8:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
ol9:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
rhel:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
rhel7:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
rhel8:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
rhel9:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
rocky:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
rocky8:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
rocky9:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
ubuntu:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
ubuntu16:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
ubuntu18:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
ubuntu20:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
tcpConnect:
|
||||
properties:
|
||||
address:
|
||||
@@ -1000,6 +1379,19 @@ spec:
|
||||
exclude:
|
||||
type: BoolString
|
||||
type: object
|
||||
udpPortStatus:
|
||||
properties:
|
||||
collectorName:
|
||||
type: string
|
||||
exclude:
|
||||
type: BoolString
|
||||
interface:
|
||||
type: string
|
||||
port:
|
||||
type: integer
|
||||
required:
|
||||
- port
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
||||
@@ -1009,9 +1401,3 @@ spec:
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.7.0
|
||||
controller-gen.kubebuilder.io/version: v0.11.2
|
||||
creationTimestamp: null
|
||||
name: hostpreflights.troubleshoot.sh
|
||||
spec:
|
||||
@@ -41,8 +40,14 @@ spec:
|
||||
properties:
|
||||
blockDevices:
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
checkName:
|
||||
type: string
|
||||
collectorName:
|
||||
type: string
|
||||
exclude:
|
||||
type: BoolString
|
||||
includeUnmountedPartitions:
|
||||
@@ -82,6 +87,8 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
strict:
|
||||
type: BoolString
|
||||
required:
|
||||
- includeUnmountedPartitions
|
||||
- minimumAcceptableSize
|
||||
@@ -89,6 +96,10 @@ spec:
|
||||
type: object
|
||||
certificate:
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
checkName:
|
||||
type: string
|
||||
collectorName:
|
||||
@@ -127,13 +138,21 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
strict:
|
||||
type: BoolString
|
||||
required:
|
||||
- outcomes
|
||||
type: object
|
||||
cpu:
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
checkName:
|
||||
type: string
|
||||
collectorName:
|
||||
type: string
|
||||
exclude:
|
||||
type: BoolString
|
||||
outcomes:
|
||||
@@ -168,11 +187,17 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
strict:
|
||||
type: BoolString
|
||||
required:
|
||||
- outcomes
|
||||
type: object
|
||||
diskUsage:
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
checkName:
|
||||
type: string
|
||||
collectorName:
|
||||
@@ -211,11 +236,17 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
strict:
|
||||
type: BoolString
|
||||
required:
|
||||
- outcomes
|
||||
type: object
|
||||
filesystemPerformance:
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
checkName:
|
||||
type: string
|
||||
collectorName:
|
||||
@@ -254,13 +285,21 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
strict:
|
||||
type: BoolString
|
||||
required:
|
||||
- outcomes
|
||||
type: object
|
||||
hostOS:
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
checkName:
|
||||
type: string
|
||||
collectorName:
|
||||
type: string
|
||||
exclude:
|
||||
type: BoolString
|
||||
outcomes:
|
||||
@@ -295,13 +334,21 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
strict:
|
||||
type: BoolString
|
||||
required:
|
||||
- outcomes
|
||||
type: object
|
||||
hostServices:
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
checkName:
|
||||
type: string
|
||||
collectorName:
|
||||
type: string
|
||||
exclude:
|
||||
type: BoolString
|
||||
outcomes:
|
||||
@@ -336,11 +383,17 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
strict:
|
||||
type: BoolString
|
||||
required:
|
||||
- outcomes
|
||||
type: object
|
||||
http:
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
checkName:
|
||||
type: string
|
||||
collectorName:
|
||||
@@ -379,11 +432,17 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
strict:
|
||||
type: BoolString
|
||||
required:
|
||||
- outcomes
|
||||
type: object
|
||||
httpLoadBalancer:
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
checkName:
|
||||
type: string
|
||||
collectorName:
|
||||
@@ -422,13 +481,21 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
strict:
|
||||
type: BoolString
|
||||
required:
|
||||
- outcomes
|
||||
type: object
|
||||
ipv4Interfaces:
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
checkName:
|
||||
type: string
|
||||
collectorName:
|
||||
type: string
|
||||
exclude:
|
||||
type: BoolString
|
||||
outcomes:
|
||||
@@ -463,13 +530,21 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
strict:
|
||||
type: BoolString
|
||||
required:
|
||||
- outcomes
|
||||
type: object
|
||||
kernelModules:
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
checkName:
|
||||
type: string
|
||||
collectorName:
|
||||
type: string
|
||||
exclude:
|
||||
type: BoolString
|
||||
outcomes:
|
||||
@@ -504,13 +579,21 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
strict:
|
||||
type: BoolString
|
||||
required:
|
||||
- outcomes
|
||||
type: object
|
||||
memory:
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
checkName:
|
||||
type: string
|
||||
collectorName:
|
||||
type: string
|
||||
exclude:
|
||||
type: BoolString
|
||||
outcomes:
|
||||
@@ -545,11 +628,115 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
strict:
|
||||
type: BoolString
|
||||
required:
|
||||
- outcomes
|
||||
type: object
|
||||
subnetAvailable:
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
checkName:
|
||||
type: string
|
||||
collectorName:
|
||||
type: string
|
||||
exclude:
|
||||
type: BoolString
|
||||
outcomes:
|
||||
items:
|
||||
properties:
|
||||
fail:
|
||||
properties:
|
||||
message:
|
||||
type: string
|
||||
uri:
|
||||
type: string
|
||||
when:
|
||||
type: string
|
||||
type: object
|
||||
pass:
|
||||
properties:
|
||||
message:
|
||||
type: string
|
||||
uri:
|
||||
type: string
|
||||
when:
|
||||
type: string
|
||||
type: object
|
||||
warn:
|
||||
properties:
|
||||
message:
|
||||
type: string
|
||||
uri:
|
||||
type: string
|
||||
when:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
strict:
|
||||
type: BoolString
|
||||
required:
|
||||
- outcomes
|
||||
type: object
|
||||
systemPackages:
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
checkName:
|
||||
type: string
|
||||
collectorName:
|
||||
type: string
|
||||
exclude:
|
||||
type: BoolString
|
||||
outcomes:
|
||||
items:
|
||||
properties:
|
||||
fail:
|
||||
properties:
|
||||
message:
|
||||
type: string
|
||||
uri:
|
||||
type: string
|
||||
when:
|
||||
type: string
|
||||
type: object
|
||||
pass:
|
||||
properties:
|
||||
message:
|
||||
type: string
|
||||
uri:
|
||||
type: string
|
||||
when:
|
||||
type: string
|
||||
type: object
|
||||
warn:
|
||||
properties:
|
||||
message:
|
||||
type: string
|
||||
uri:
|
||||
type: string
|
||||
when:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
strict:
|
||||
type: BoolString
|
||||
required:
|
||||
- outcomes
|
||||
type: object
|
||||
tcpConnect:
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
checkName:
|
||||
type: string
|
||||
collectorName:
|
||||
@@ -588,11 +775,17 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
strict:
|
||||
type: BoolString
|
||||
required:
|
||||
- outcomes
|
||||
type: object
|
||||
tcpLoadBalancer:
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
checkName:
|
||||
type: string
|
||||
collectorName:
|
||||
@@ -631,11 +824,17 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
strict:
|
||||
type: BoolString
|
||||
required:
|
||||
- outcomes
|
||||
type: object
|
||||
tcpPortStatus:
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
checkName:
|
||||
type: string
|
||||
collectorName:
|
||||
@@ -674,13 +873,21 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
strict:
|
||||
type: BoolString
|
||||
required:
|
||||
- outcomes
|
||||
type: object
|
||||
time:
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
checkName:
|
||||
type: string
|
||||
collectorName:
|
||||
type: string
|
||||
exclude:
|
||||
type: BoolString
|
||||
outcomes:
|
||||
@@ -715,6 +922,57 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
strict:
|
||||
type: BoolString
|
||||
required:
|
||||
- outcomes
|
||||
type: object
|
||||
udpPortStatus:
|
||||
properties:
|
||||
annotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
checkName:
|
||||
type: string
|
||||
collectorName:
|
||||
type: string
|
||||
exclude:
|
||||
type: BoolString
|
||||
outcomes:
|
||||
items:
|
||||
properties:
|
||||
fail:
|
||||
properties:
|
||||
message:
|
||||
type: string
|
||||
uri:
|
||||
type: string
|
||||
when:
|
||||
type: string
|
||||
type: object
|
||||
pass:
|
||||
properties:
|
||||
message:
|
||||
type: string
|
||||
uri:
|
||||
type: string
|
||||
when:
|
||||
type: string
|
||||
type: object
|
||||
warn:
|
||||
properties:
|
||||
message:
|
||||
type: string
|
||||
uri:
|
||||
type: string
|
||||
when:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
strict:
|
||||
type: BoolString
|
||||
required:
|
||||
- outcomes
|
||||
type: object
|
||||
@@ -951,6 +1209,127 @@ spec:
|
||||
exclude:
|
||||
type: BoolString
|
||||
type: object
|
||||
run:
|
||||
properties:
|
||||
args:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
collectorName:
|
||||
type: string
|
||||
command:
|
||||
type: string
|
||||
exclude:
|
||||
type: BoolString
|
||||
required:
|
||||
- args
|
||||
- command
|
||||
type: object
|
||||
subnetAvailable:
|
||||
properties:
|
||||
CIDRRangeAlloc:
|
||||
type: string
|
||||
collectorName:
|
||||
type: string
|
||||
desiredCIDR:
|
||||
type: integer
|
||||
exclude:
|
||||
type: BoolString
|
||||
required:
|
||||
- CIDRRangeAlloc
|
||||
- desiredCIDR
|
||||
type: object
|
||||
systemPackages:
|
||||
properties:
|
||||
amzn:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
amzn2:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
centos:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
centos7:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
centos8:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
centos9:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
collectorName:
|
||||
type: string
|
||||
exclude:
|
||||
type: BoolString
|
||||
ol:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
ol7:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
ol8:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
ol9:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
rhel:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
rhel7:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
rhel8:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
rhel9:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
rocky:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
rocky8:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
rocky9:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
ubuntu:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
ubuntu16:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
ubuntu18:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
ubuntu20:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
tcpConnect:
|
||||
properties:
|
||||
address:
|
||||
@@ -1000,6 +1379,19 @@ spec:
|
||||
exclude:
|
||||
type: BoolString
|
||||
type: object
|
||||
udpPortStatus:
|
||||
properties:
|
||||
collectorName:
|
||||
type: string
|
||||
exclude:
|
||||
type: BoolString
|
||||
interface:
|
||||
type: string
|
||||
port:
|
||||
type: integer
|
||||
required:
|
||||
- port
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
remoteCollectors:
|
||||
@@ -1219,6 +1611,27 @@ spec:
|
||||
exclude:
|
||||
type: BoolString
|
||||
type: object
|
||||
subnetAvailable:
|
||||
properties:
|
||||
CIDRRangeAlloc:
|
||||
type: string
|
||||
collectorName:
|
||||
type: string
|
||||
desiredCIDR:
|
||||
type: integer
|
||||
exclude:
|
||||
type: BoolString
|
||||
required:
|
||||
- CIDRRangeAlloc
|
||||
- desiredCIDR
|
||||
type: object
|
||||
systemPackages:
|
||||
properties:
|
||||
collectorName:
|
||||
type: string
|
||||
exclude:
|
||||
type: BoolString
|
||||
type: object
|
||||
tcpConnect:
|
||||
properties:
|
||||
address:
|
||||
@@ -1268,6 +1681,19 @@ spec:
|
||||
exclude:
|
||||
type: BoolString
|
||||
type: object
|
||||
udpPortStatus:
|
||||
properties:
|
||||
collectorName:
|
||||
type: string
|
||||
exclude:
|
||||
type: BoolString
|
||||
interface:
|
||||
type: string
|
||||
port:
|
||||
type: integer
|
||||
required:
|
||||
- port
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
||||
@@ -1277,9 +1703,3 @@ spec:
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,9 @@
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.7.0
|
||||
controller-gen.kubebuilder.io/version: v0.11.2
|
||||
creationTimestamp: null
|
||||
name: redactors.troubleshoot.sh
|
||||
spec:
|
||||
@@ -79,9 +78,3 @@ spec:
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.7.0
|
||||
controller-gen.kubebuilder.io/version: v0.11.2
|
||||
creationTimestamp: null
|
||||
name: remotecollectors.troubleshoot.sh
|
||||
spec:
|
||||
@@ -284,6 +283,27 @@ spec:
|
||||
exclude:
|
||||
type: BoolString
|
||||
type: object
|
||||
subnetAvailable:
|
||||
properties:
|
||||
CIDRRangeAlloc:
|
||||
type: string
|
||||
collectorName:
|
||||
type: string
|
||||
desiredCIDR:
|
||||
type: integer
|
||||
exclude:
|
||||
type: BoolString
|
||||
required:
|
||||
- CIDRRangeAlloc
|
||||
- desiredCIDR
|
||||
type: object
|
||||
systemPackages:
|
||||
properties:
|
||||
collectorName:
|
||||
type: string
|
||||
exclude:
|
||||
type: BoolString
|
||||
type: object
|
||||
tcpConnect:
|
||||
properties:
|
||||
address:
|
||||
@@ -333,6 +353,19 @@ spec:
|
||||
exclude:
|
||||
type: BoolString
|
||||
type: object
|
||||
udpPortStatus:
|
||||
properties:
|
||||
collectorName:
|
||||
type: string
|
||||
exclude:
|
||||
type: BoolString
|
||||
interface:
|
||||
type: string
|
||||
port:
|
||||
type: integer
|
||||
required:
|
||||
- port
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
nodeSelector:
|
||||
@@ -346,9 +379,3 @@ spec:
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,6 +3,7 @@ kind: Collector
|
||||
metadata:
|
||||
name: collector-sample
|
||||
spec:
|
||||
uri: https://raw.githubusercontent.com/replicatedhq/troubleshoot-specs/main/in-cluster/default.yaml
|
||||
collectors:
|
||||
- clusterInfo: {}
|
||||
- clusterResources: {}
|
||||
|
||||
@@ -5,13 +5,19 @@ release:
|
||||
name: troubleshoot
|
||||
builds:
|
||||
- id: preflight
|
||||
# NOTE: if you add any additional goos/goarch values, ensure you update ../.github/workflows/build-test-deploy.yaml
|
||||
# specifically the matrix values for goreleaser-test
|
||||
goos:
|
||||
- linux
|
||||
- darwin
|
||||
- windows
|
||||
goarch:
|
||||
- amd64
|
||||
- arm
|
||||
- arm64
|
||||
ignore:
|
||||
- goos: windows
|
||||
goarch: arm
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
main: cmd/preflight/main.go
|
||||
@@ -30,7 +36,11 @@ builds:
|
||||
- windows
|
||||
goarch:
|
||||
- amd64
|
||||
- arm
|
||||
- arm64
|
||||
ignore:
|
||||
- goos: windows
|
||||
goarch: arm
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
main: cmd/troubleshoot/main.go
|
||||
@@ -49,7 +59,11 @@ builds:
|
||||
- windows
|
||||
goarch:
|
||||
- amd64
|
||||
- arm
|
||||
- arm64
|
||||
ignore:
|
||||
- goos: windows
|
||||
goarch: arm
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
main: cmd/collect/main.go
|
||||
|
||||
@@ -16,6 +16,17 @@ spec:
|
||||
- from: LICENSE
|
||||
to: .
|
||||
bin: preflight
|
||||
- selector:
|
||||
matchLabels:
|
||||
os: linux
|
||||
arch: arm
|
||||
{{addURIAndSha "https://github.com/replicatedhq/troubleshoot/releases/download/{{ .TagName }}/preflight_linux_arm_6.tar.gz" .TagName }}
|
||||
files:
|
||||
- from: preflight
|
||||
to: .
|
||||
- from: LICENSE
|
||||
to: .
|
||||
bin: preflight
|
||||
- selector:
|
||||
matchLabels:
|
||||
os: darwin
|
||||
|
||||
@@ -16,6 +16,17 @@ spec:
|
||||
- from: LICENSE
|
||||
to: .
|
||||
bin: support-bundle
|
||||
- selector:
|
||||
matchLabels:
|
||||
os: linux
|
||||
arch: arm
|
||||
{{addURIAndSha "https://github.com/replicatedhq/troubleshoot/releases/download/{{ .TagName }}/support-bundle_linux_arm_6.tar.gz" .TagName }}
|
||||
files:
|
||||
- from: support-bundle
|
||||
to: .
|
||||
- from: LICENSE
|
||||
to: .
|
||||
bin: support-bundle
|
||||
- selector:
|
||||
matchLabels:
|
||||
os: darwin
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
# Run collectors concurrently
|
||||
|
||||
## Goals
|
||||
|
||||
Increase the speed at which collectors complete.
|
||||
|
||||
## Non Goals
|
||||
|
||||
|
||||
## Background
|
||||
|
||||
Currently all collectors run sequentially, in the order in which they are specified in the spec. This is implied, and has not been guaranteed. With the addition of the ability to supply multiple specs, the order is no longer predicatble.
|
||||
|
||||
Although sequence is not guaranteed for any collectors, #768 ensures that the `clusterResources` collector runs first, so that the list of resources does not include those that are started during the Troubleshoot collection sequence.
|
||||
|
||||
The performance for support-bundle and preflight runs is important to the end user experience of the product. There are examples where a support bundle takes multiple minutes to complete, and folks are left wondering if the process has hung or crashed. Preflights that take too long will simply be skipped, which leads to problems with installation being difficult to identify.
|
||||
|
||||
## High-Level Design
|
||||
|
||||
Switch collectors and host collectors to use goroutines to collect (concurrently). This should run the list of collectors of `clusterResources` type first, then the remainder concurrently when `clusterResources` is complete.
|
||||
|
||||
## Detailed Design
|
||||
|
||||
Tasks that can be split to separate merges (in order):
|
||||
|
||||
* Switch all collectors to use goroutines to collect (concurrently).
|
||||
* In `supportbundle.runCollectors()`, refactor to use a `go func()` pattern to run all the collectors that are not `clusterResources` concurrently. Check that the first in the list is `clusterResources` and run that separately, prior to the others.
|
||||
* This task should introduce an optional concurrency limit field, default to, say, 10, which limits the number of goroutines/collectors that can run at any given time.
|
||||
* This task should improve the collection speed of in-cluster collectors and preflights
|
||||
|
||||
* Switch Host Collectors to use goroutines for concurrent collection.
|
||||
* In `supportbundle.runHostCollectors()`, refactor to use a `go func()` pattern for each collector.
|
||||
* No need to honor the same concurrency limit as host collectors do not load the Kubernetes API
|
||||
|
||||
* Switch Host Preflights to use goroutines - `preflight.CollectHost()` runs `go func()` for each collector.
|
||||
|
||||
* Switch in-cluster Preflights to use goroutines - `preflight.Collect()` runs `go func()` for each collector.
|
||||
* Ensure `clusterResources` runs in advance of the others so that pods started by collectors do not produce an error in the results.
|
||||
|
||||
## Limitations
|
||||
|
||||
Relies on splitting up the list of collectors into `clusterResources` and others.
|
||||
|
||||
Collisions between specs (e.g. if `runPod` has multiple specs with the same name) are not handled. At the current stage with collectors running sequentially, if two collectors write to the same file the second overwrites the data from the first. If collectors run concurrently, there can be issues creating multiple pods with the same name, and issues with concurrent access to the target file. This issue is tracked in [#895](https://github.com/replicatedhq/troubleshoot/issues/895)
|
||||
|
||||
This proposal excludes Remote Collectors.
|
||||
## Assumptions
|
||||
|
||||
* The Kubernetes API can handle the load of collectors running concurrently, including when the pod logs collector runs.
|
||||
|
||||
## Testing
|
||||
|
||||
Any new function will need unit tests.
|
||||
|
||||
The existing Collect functions will need unit tests altered (or added).
|
||||
|
||||
We will need to ensure that `clusterResources` is collected prior to others.
|
||||
|
||||
## Documentation
|
||||
|
||||
There should be a note in https://troubleshoot.sh/docs/collect/ ensuring that folks do not expect the collectors to run in any particular order.
|
||||
|
||||
## Alternatives Considered
|
||||
|
||||
None.
|
||||
## Security Considerations
|
||||
|
||||
None identified.
|
||||
@@ -0,0 +1,76 @@
|
||||
# ADR 001: remove IP address redaction by default
|
||||
|
||||
## Context
|
||||
|
||||
Since PR #8 IP addresses have automatically been redacted throughout support bundles. This was originally
|
||||
added so that folks with security requirements that include not sharing IP addresses can avoid needing to add
|
||||
individual redactors for that purpose.
|
||||
|
||||
The general requirement for environments that protect network infrastructure from being communicated outside also
|
||||
includes hostnames, port numbers, and mac addresses. The Troubleshoot code does not redact these.
|
||||
|
||||
The experience of support engineers making use of Troubleshoot support bundles has been that in many cases,
|
||||
a further set of logs, and data collection information needs to be collected for issues that involve network
|
||||
infrastructure in order to be able to assist. This involves collection that does not redact IP addresses, and
|
||||
introduces significant delays in the resolution of issues due to back and forth.
|
||||
|
||||
A review of Replicated support cases where end users posted an IP address in GitHub found 71 different issues
|
||||
in 2022 (as of October 2022). This doesn't cover uploaded files, phone calls, screen shares, etc. It also
|
||||
doesn't include anything else networking like mac address, hostnames, ports.
|
||||
|
||||
The problem discussed in this document:
|
||||
|
||||
* Users of Troubleshoot need to avoid redaction if they have networking issues, in order to share IP addresses
|
||||
that are redacted by default.
|
||||
* The user experience of the product is based around "define what you want", however with default redactors built
|
||||
into the product in addition to the defined spec is confusing and, in some cases, problematic if you do not want
|
||||
the built in redactors.
|
||||
* A default set of redactors gives product users a false sense of security in that though the default redactors
|
||||
do cover some redaction, they do not cover every possible combination for every particular sensitive item.
|
||||
Redaction of hostnames is almost impossible given the freeform nature of hostnames, and the built in Password
|
||||
redactor does not cover all passwords, merely a particular json combination.
|
||||
|
||||
## Decision
|
||||
|
||||
We will remove the code that redacts IP addresses by default from Troubleshoot. Folks that wish to redact IP addresses will
|
||||
need to add that redactor to their individual Troubleshoot specs.
|
||||
|
||||
## Solution
|
||||
|
||||
The following changes need to be made:
|
||||
|
||||
* [Documentation](https://troubleshoot.sh/docs/redact/ip-addresses/) for the IP address redaction needs altering to reflect that Troubleshoot
|
||||
does not automatically redact IP addresses, but if users wish to there is an example yaml spec available.
|
||||
* Removal of the IP address redactor from [the code](https://github.com/replicatedhq/troubleshoot/blob/v0.45.0/pkg/redact/redact.go#L170)
|
||||
* Clear release notes on release of this change, communicating that those wishing to redact IP addresses need to add that redactor to their spec.
|
||||
* Possible broadcast communication since this is a change to default behavior.
|
||||
|
||||
## Status
|
||||
|
||||
Proposed
|
||||
|
||||
## Consequences
|
||||
|
||||
Describe the resulting context, after applying the decision. All consequences should be listed here,
|
||||
not just the "positive" ones. A particular decision may have positive, negative, and neutral consequences,
|
||||
but all of them affect the team and project in the future.
|
||||
|
||||
Those that wish to have IP addresses redacted by Troubleshoot need to ensure that the redactor specified during `support-bundle` runs includes a
|
||||
regex for IP address redaction.
|
||||
|
||||
Example regex for IP redaction:
|
||||
|
||||
```yaml
|
||||
apiVersion: troubleshoot.sh/v1beta2
|
||||
kind: Redactor
|
||||
metadata:
|
||||
name: IP Addresses
|
||||
spec:
|
||||
redactors:
|
||||
- name: Redact ipv4 addresses
|
||||
removals:
|
||||
regex:
|
||||
- redactor: '(?P<mask>\b(?P<drop>25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?P<drop>25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?P<drop>25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?P<drop>25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b)'
|
||||
```
|
||||
|
||||
Folks that have not specified the IP address regex above will, on support bundle creation, share their IP address information in that bundle by default.
|
||||
@@ -0,0 +1,37 @@
|
||||
# ADR 002: Mergeable preflight specs
|
||||
|
||||
When the `preflight` binary, or pacakge, is called, it supports only one spec definition at a time.
|
||||
|
||||
Recent changes in Troubleshoot allow the `support-bundle` binary to be called with multiple specs at a time. This allows cluster components to contribute independant Troubleshoot specs for their scope, and have Troubleshoot assemble them at run time.
|
||||
|
||||
Tools such as kURL have components which are maintained with a degree of separation to one another. It would be helpful to the maintainers of such projects to be able to call `preflight` specifying a number of specs at runtime, allowing Troubleshoot to assemble them into one spec for collection/analysis.
|
||||
|
||||
Currently if the `preflight` binary is called with multiple specs, it simply ignores all after the first.
|
||||
|
||||
## Decision
|
||||
|
||||
Modify the `preflight` CLI and package to be able to read multiple args rather than just one.
|
||||
|
||||
Introduce a merge mechanism in the same way that the `support-bundle` binary runs, to merge and deduplicate Preflight specs.
|
||||
|
||||
## Status
|
||||
|
||||
Proposed
|
||||
|
||||
## Consequences
|
||||
|
||||
There are no backward compatibility consequences or breaking changes in this proposal.
|
||||
|
||||
The project benefits:
|
||||
* Folks maintaining kURL add-ons can contribute unique preflight specs for their add-on (and the same for other projects simlarly structured)
|
||||
* Folks using `preflight` from the CLI without other applications (e.g. for a Helm install) are able to specify a list of preflights for their application rather than having to assemble one spec for each environment.
|
||||
|
||||
## Design notes
|
||||
|
||||
This proposal does not include adding the `uri:` field to `kind: Preflight`.
|
||||
|
||||
The file `cmd/preflight/cli/root.go` calls `preflight.RunPreflights` with `args[0]` which is likely to need to change to just `args`.
|
||||
|
||||
Func `RunPreflights` takes a single string arg (`arg string`) for the spec definition. This is likely to need to change to `arg []string`.
|
||||
|
||||
File `cmd/troubleshoot/cli/run.go` loops through the list of args, concatenating them together. A similar process is suitable for this change.
|
||||
@@ -0,0 +1,81 @@
|
||||
# Architecture Decision Records
|
||||
|
||||
_ADR_ for short.
|
||||
|
||||
## What is an Architecturally Significant Decision?
|
||||
|
||||
See [Documenting Architecture
|
||||
Decisions](http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions)
|
||||
for more information.
|
||||
|
||||
The basic idea is to capture key decisions having to do with anything _architectural_
|
||||
in a way that promotes better communication than simple word-of-mouth.
|
||||
|
||||
What is an _architectural_ decision? If one or more of the following ideas apply you
|
||||
might be dealing with an architectural decision.
|
||||
|
||||
Does the design decision...
|
||||
|
||||
* Alter externally visible system properties?
|
||||
* Modify public interfaces?
|
||||
* Directly influence high priority quality attributes?
|
||||
* Include or remove dependencies?
|
||||
* Result from a discussion where you learned more about technical or business constraints?
|
||||
* Involve taking on strategic technical debt?
|
||||
* Change the structures of the system (static, dynamic, or physical)?
|
||||
* Require other developers to update construction techniques or development environments?
|
||||
|
||||
|
||||
## Template
|
||||
|
||||
Use this template in any new ADRs. Replace the help text as you write the ADR.
|
||||
|
||||
```
|
||||
# ADR N: Brief Decision Title
|
||||
|
||||
Context goes here.
|
||||
|
||||
Describe the forces at play, including technological, political, social, and project local.
|
||||
These forces are likely in tension, and should be called out as such. The language in this
|
||||
section is value-neutral. It is simply describing facts.
|
||||
|
||||
## Decision
|
||||
|
||||
This section describes our response to these forces. It is stated in full sentences,
|
||||
with active voice. "We will ..."
|
||||
|
||||
|
||||
## Status
|
||||
|
||||
choose one: [Proposed | Accepted | Deprecated | Superseded]
|
||||
|
||||
if deprecated, include a rationale.
|
||||
|
||||
If superseded, include a link to the new ADR
|
||||
|
||||
|
||||
## Consequences
|
||||
|
||||
Describe the resulting context, after applying the decision. All consequences should be listed here,
|
||||
not just the "positive" ones. A particular decision may have positive, negative, and neutral consequences,
|
||||
but all of them affect the team and project in the future.
|
||||
```
|
||||
|
||||
## Tips and Hints
|
||||
|
||||
* Titles should be descriptive, concise, and precise
|
||||
* The whole document should be one or two pages long at most.
|
||||
* Think of the document as a conversation with a future developer. This means write well and use full
|
||||
sentences.
|
||||
* Update consequences as they become known. The ADR becomes like a diary for seeing how the design
|
||||
decisions we make impact the system over time.
|
||||
* Include diagrams as necessary.
|
||||
|
||||
|
||||
## References
|
||||
|
||||
Nygard, Michael. Documenting Architecture Decisions, from _Think Relevance_ blog. [Web](http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions)
|
||||
|
||||
Kruchten, Philippe. _The Decision View's Role in Software Architecture Practice_, IEEE Software 26:36-42, February 2009
|
||||
|
||||
Tyree, J. and Akerman, A. _Architecture Decisions: Demystifying Architecture_, IEEE Software 22:2:19-27, March-April 2005 [PDF](http://www.utdallas.edu/~chung/SA/zz-Impreso-architecture_decisions-tyree-05.pdf)
|
||||
@@ -0,0 +1,27 @@
|
||||
# Troubleshoot Design Principles
|
||||
|
||||
This document captures design principles that the Troubleshoot project abides by. This is intended to provide new contributors with guidance on how to approach problems and a better understanding of what to consider and address while implementing features.
|
||||
|
||||
## Client not Cluster based
|
||||
|
||||
Troubleshoot has to communicate with the Kubernetes API server to gather information. However, Troubleshoot should interact with the cluster as little as reasonably possible and has no intention of having a persistent in-cluster presence. There are several reasons for this approach, in no particular order those include:
|
||||
|
||||
* Users experiencing an issue in their cluster may discover Troubleshoot after they have a problem and requiring installed components may exclude them from solving their problem.
|
||||
* A user may have limited cluster access and requiring cluster wide installation like a CRD or Operator can prevent them for using tools to recover from their errors.
|
||||
* By definition Troubleshoot is being used because there is an issue with the cluster, to prevent exasperating the issue Troubleshoot should avoid writing to the cluster.
|
||||
|
||||
## Tools not specs
|
||||
|
||||
The Troubleshoot project should include tools which can be used to diagnose issues but is not attempting to include Specs built into the project itself. The number of issues and projects which could benefit from Troubleshoot is very large and we intended to enable those projects to better support their project. It is unreasonable and undesirable for Troubleshoot to be the source of truth for all possible cluster and software issues.
|
||||
|
||||
## Fail forward
|
||||
|
||||
Clusters with issues can be unpredictable, the scope of error conditions is likely unbounded. Troubleshoot should keep this in mind when doing error handling and fail forward proceeding with as much of the intended operation as possible while logging the errors. For example if a collector fails to collect information that should not prevent other collectors from running. Any condition that causes Troubleshoot to hang or not complete a run is considered a bug.
|
||||
|
||||
## Provide a predictable user experience
|
||||
|
||||
When things go wrong people can be stressed and stressed people aren't likely to thoroughly read documentation. Whenever possible default values, command line flags, etc should be set to provide a user the best experience possible with the input provided. Some examples of this include:
|
||||
|
||||
* When accepting flags for things like Namespaces, as much as possible, use the same syntax that `kubectl` accepts which users are likely to try instinctively.
|
||||
* Default to gathering more information not less, rarely is it easier to diagnose an issue with less information.
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
# Consolidate collector code
|
||||
|
||||
## Goals
|
||||
|
||||
Reduce code maintenance needs.
|
||||
|
||||
Improve consistency between preflight and support-bundle.
|
||||
|
||||
## Non Goals
|
||||
|
||||
## Background
|
||||
|
||||
In the current Troubleshoot code base, there are three separate paths to running collectors. These include preflights, support-bundle, and the collect package. The three have diverged over time and are different to one another, but do not appear to have any need to be separate. This is confusing and likely to introduce errors in the future.
|
||||
|
||||
## High-Level Design
|
||||
|
||||
* Add a `collect` package public API that can be called to run the collect logic, from any other package
|
||||
* change the preflight, support-bundle and collect binaries to call that API rather than their own collect routines
|
||||
|
||||
## Detailed Design
|
||||
|
||||
Package `preflight`:
|
||||
* Remove `CollectHost`, `Collect` and `CollectRemote`
|
||||
|
||||
Package `supportbundle`:
|
||||
* Remove `runCollectors`, `CollectSupportBundleFromSpec`, and associated code
|
||||
|
||||
Package `collect`:
|
||||
* Add a replacement for `runCollectors`, `CollectSupportBundleFromSpec` taken from `supportbundle`
|
||||
* Add replacements for `CollectHost`, `Collect` and `CollectRemote` taken from `preflight`
|
||||
* Where the above duplicate functionality, alter the `supportbundle` or `preflight` packages to ensure that a single new function handles the requirement
|
||||
|
||||
CLI packages:
|
||||
* Alter to use the public functions from `collect`
|
||||
|
||||
## Limitations
|
||||
|
||||
Breaking change - KOTS at least imports `CollectSupportBundleFromSpec` plus potentially others.
|
||||
|
||||
This does not affect the analysis and redaction portions of code.
|
||||
|
||||
## Assumptions
|
||||
|
||||
* there is no need to run collectors differently between preflight and support-bundle
|
||||
|
||||
## Testing
|
||||
|
||||
Any new function will need unit tests.
|
||||
|
||||
Existing tests will need to be altered, and possibly consolidated.
|
||||
|
||||
## Documentation
|
||||
|
||||
The public function to call collection should be documented and at that point regarded stable.
|
||||
|
||||
## Alternatives Considered
|
||||
|
||||
## Security Considerations
|
||||
|
||||
None identified.
|
||||
|
||||
## Related changes
|
||||
|
||||
TODO:
|
||||
* make an API for analyze and redact
|
||||
* create an API that calls collect, redact, and analyze - and decide if that can be called by preflight and support-bundle
|
||||
@@ -0,0 +1,138 @@
|
||||
# Provide the ability to specify multiple Troubleshoot specs in one run of support-bundle or preflight
|
||||
|
||||
Troubleshoot doesn't have a modular way for different components to specify specifications. If a software project wanted to include project specific items the end user would have a hard time knowing where to find those and how to collect them. Furthermore if multiple projects were to do this the user would have to run troubleshoot multiple times.
|
||||
|
||||
Ideally troubleshoot would allow merging of specs to allow building a spec either automatically or influenced by user input to target specific needs.
|
||||
|
||||
## Goals
|
||||
|
||||
Primary goal: Allow folks that develop a particular component to maintain Troubleshoot specs for that component, including Vendors for their application.
|
||||
|
||||
Long term goal: allow folks to update the component specs without needing to run any other upgrades.
|
||||
|
||||
This proposal initially adds the ability to supply multiple support bundle specs for a single run of support-bundle and/or preflight so that:
|
||||
|
||||
* when Troubleshoot runs, the spec it uses is an aggregate of multiple specs from the same source - yaml file, URL, configMap, or (new) CRD
|
||||
* each software component can contribute a Troubleshoot spec that is specific to that software
|
||||
* Ownership of each individual spec per component transfers to the owner of that component
|
||||
|
||||
This will:
|
||||
|
||||
* Ensure support bundles generated by users are comprehensive and contain all needed information for a project maintainer to action
|
||||
* Allow multiple specs from different projects, should a cluster have multiple projects using Troubleshoot
|
||||
* Software developers to continually update specs for components to easily identify known issues and reduce support noise.
|
||||
|
||||
## Non Goals
|
||||
|
||||
* Compatibility with previous URL, configMap and yaml specs, both Redactors and SupportBundle types
|
||||
* Maintain the ability to read secrets from the Kubernetes API
|
||||
|
||||
## Background
|
||||
|
||||
When users of Troubleshoot create a support bundle from the CLI, they use a single spec that is provided from:
|
||||
|
||||
* A secret installed in the cluster by an application such as [KOTS](kots.io)
|
||||
* A url like <http://kots.io>
|
||||
* some other single example spec, e.g. <https://github.com/replicatedhq/troubleshoot-specs>
|
||||
|
||||
When KOTS collects a support bundles from the KOTS UI, the spec is a [merged](https://github.com/replicatedhq/kots/blob/main/pkg/supportbundle/spec.go#L426) combination of the following:
|
||||
|
||||
* The [default spec](https://github.com/replicatedhq/kots/blob/main/pkg/supportbundle/defaultspec/spec.yaml) in the kots code
|
||||
* The spec provided by the Vendor’s application bundle
|
||||
* This merged spec is deduplicated by kots [here](https://github.com/replicatedhq/kots/blob/main/pkg/supportbundle/spec.go#L217).
|
||||
|
||||
Redactors are [hard coded](https://github.com/replicatedhq/troubleshoot/blob/main/pkg/redact/redact.go#L160) into Troubleshoot as well as supplied in the spec.
|
||||
|
||||
Although we’re currently making strides in improving the Troubleshoot project by creating new collectors, analyzers, and specs, we have no way to more quickly deliver Troubleshoot improvements to installations in the field without updating the kots application and pushing a new release, or upgrading kots to a new version.
|
||||
|
||||
When folks find a support issue that could have been identified by Troubleshoot, we ask them to write a new collector, and/or analyzer, for that information. However, if we do that, the new collector/analyzer is not easily available to end users.
|
||||
|
||||
Some of the useful features of Troubleshoot are actually implemented as part of KOTS, while both open source Troubleshoot should address this independently.
|
||||
|
||||
## High-Level Design
|
||||
|
||||
Add CRD support to Troubleshoot:
|
||||
|
||||
* Design a custom resource (CRD) that allows adding spec(s) to the Kubernetes cluster using `kubectl`. There is no need to extend this to use [API server aggregation](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/#api-server-aggregation).
|
||||
* Update Troubleshoot to allow consuming the first object found of the new custom resource, by default - i.e. if there are no specs provided on the CLI or entrypoint, use CRD
|
||||
* Once merge is implemented, update Troubleshoot to consume and merge all the instances of the CRD.
|
||||
* To minimize code changes in Troubleshoot, we could implement two CRDs, of `type: SupportBundle` and `type: Redactor`. However, there is no specific need to separate the two and it maybe advantageous to keep things simple, combining them.
|
||||
|
||||
Allow multiple specs to be merged by Troubleshoot:
|
||||
|
||||
* create an interface for collectors, analyzers, and redactors to merge
|
||||
* each collector/analyzer/redactor can use a generic implementation of the interface for the merge, or can use a specific one for that task if that particular collector will benefit from a more intelligent merge.
|
||||
* the spec merge code in kots can, at this stage, be removed once kots ships CRDs for the Troubleshoot specs
|
||||
|
||||
Spec sources:
|
||||
|
||||
* Alter Troubleshoot to accept multiple yaml files on the CLI
|
||||
* Create a CRD containing a spec, have Troubleshoot search for spec CRDs and combine them all when run
|
||||
* maintain the URL compatibility as is
|
||||
* maintain the configMap compatibility as is
|
||||
|
||||
## Detailed Design
|
||||
|
||||
CRD: to be designed
|
||||
|
||||
Merge:
|
||||
|
||||
* define a new interface that provides the merge functionality for collectors, analyzers, and redactors
|
||||
* there should be a generic implementation of that interface which is used by default for all objects. This can simply use `append()`.
|
||||
* specific collectors may have alternative implementations of the interface where overrides are required.
|
||||
|
||||
Particular overrides known at this point in time:
|
||||
|
||||
* clusterResources has an option namespaces config, these should be merged and deduplicated
|
||||
* Two runPod collectors with the same name and different commands are unmergable. Only one should be run and an error logged.
|
||||
* Two configMap collectors can be deduplicated and merged depending on the configurations
|
||||
* Two logs collectors likely only need deduplication to prevent collecting the same thing twice
|
||||
|
||||
## Limitations
|
||||
|
||||
### Visibility
|
||||
|
||||
Users may collect more than intended with the new implementation if all available CRD objects are run. We therefore need to be sure the Troubleshoot client allows for selection of what to run. While the default would be to run everything, a user should be able to just run specific SupportBundle specs based on labels, namespaces, etc. By doing this no functionality is lost.
|
||||
|
||||
### Airgap
|
||||
|
||||
Some of the spec locations such as URL wouldn’t work here. There may be other considerations around airgap as well.
|
||||
|
||||
Airgap installs are intentionally feature limited. Failure to retrieve new versions of specs should fail gracefully and proceed with the run.
|
||||
|
||||
As a follow up feature to improve support bundle collection Troubleshoot could gain some abilities to help manage and upgrade SupportBundles found in a cluster in a fashion that allows the user to split the discovery, download, and upgrade so they could be run on different machines.
|
||||
|
||||
An example implementation would be:
|
||||
|
||||
* A command to find, deduplicate, and output a list of SupportBundles in the cluster. The list would include at least the upstream URL and version currently installed in the cluster.
|
||||
* A command to take the output of the above command and check for updates, downloading all updated SupportBundles into a single .tgz file.
|
||||
* A command to apply the above .tgz file to the cluster upgrading any existing SupportBundles with the newer versions.
|
||||
|
||||
## Assumptions
|
||||
|
||||
* all deployments are able to deploy CRDs to the Kubernetes cluster
|
||||
|
||||
## Testing
|
||||
|
||||
## Alternatives Considered
|
||||
|
||||
### Use the existing URL functionality in Troubleshoot
|
||||
|
||||
Proposal: Provide a custom URL for each install, that when called by Troubleshoot returns a spec composed of the ‘latest’ for every component spec specified in that installation, much like we do with <https://kurl.sh/latest> now.
|
||||
|
||||
Pros:
|
||||
|
||||
* No changes required to Troubleshoot
|
||||
* Always use the latest specs for components other than the Vendor’s application
|
||||
|
||||
Cons:
|
||||
|
||||
* Would not work for airgap installations
|
||||
* Software developers need to update their application in order to get new specs from all dependencies
|
||||
* Replicated would need to provide a new API/web service to host the specs, reducing the general community applicability of troubleshoot as a stand alone project
|
||||
* Discourages individual projects from maintaining Troubleshoot specs for that project
|
||||
|
||||
## Security Considerations
|
||||
|
||||
Passing control of component specs to individual projects presents a possibility of reducing the amount of review a spec goes through for each update, allowing a spec provided by, say, a kURL addon to run collectors. The current implementation relies on the kots review process for default specs, plus the review of individual example specs. Depending on the final implementation, it is unlikely that this change itself increases any risk since the delivery of automated and default specs to Troubleshoot is maintained within kots, and/or Troubleshoot itself much as it is already.
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
# Integrate SBCTL with Troubleshoot
|
||||
|
||||
## Goals
|
||||
|
||||
Make sbctl easier to maintain by consolidating code bases.
|
||||
|
||||
Reduce code duplication.
|
||||
|
||||
Improve end-user experience and improve discoverability of sbctl.
|
||||
|
||||
## Non Goals
|
||||
|
||||
## Background
|
||||
sbctl is our command line tool for examining K8s resources inside of Support Bundles generated by our troubleshoot project. With both projects having separate code bases we see the following problems:
|
||||
|
||||
* Most users are familiar with the binaries from troubleshoot (support-bundle, preflight, etc.), but are unaware of the existince of sbctl because it's a separate project
|
||||
* sbctl and troubleshoot are naturally coupled together due to sbctl's reliance on support bundles to operate. Them being in separate repos leads to duplication of code in both projects increasing maintenance burden.
|
||||
|
||||
## High-Level Design
|
||||
Because the functionality of sbctl and Troubleshoot are so tightly coupled together, they should live in the same repository. Moreover, as opposed to maintaing a separate binary for sbctl, all sbctl commands should become subcommands of `support-bundle`
|
||||
|
||||
## Detailed Design
|
||||
The `serve` and `shell` commands become subcommands of the `support-bundle` CLI.
|
||||
|
||||
```
|
||||
./bin/support-bundle --help
|
||||
A support bundle is an archive of files, output, metrics and state
|
||||
from a server that can be used to assist when troubleshooting a Kubernetes cluster.
|
||||
|
||||
Usage:
|
||||
support-bundle [url] [flags]
|
||||
support-bundle [command]
|
||||
|
||||
Available Commands:
|
||||
analyze analyze a support bundle
|
||||
serve Start API server
|
||||
shell Start interractive shell
|
||||
completion Generate the autocompletion script for the specified shell
|
||||
...
|
||||
```
|
||||
|
||||
Similiar to the [Analyze](https://github.com/replicatedhq/troubleshoot/blob/main/cmd/troubleshoot/cli/analyze.go) subcommand, we add `serve.go` and `shell.go` to `cmd/troubleshoot/cli`
|
||||
|
||||
### Standardize Cluster Resources Collector
|
||||
* In `pkg/collect` standardize the root directory location of the Cluster Resources collector with a variable instead of repeatedly specifying it as a string - https://github.com/replicatedhq/troubleshoot/blob/main/pkg/collect/cluster_resources.go#L121.
|
||||
* Import the directory the Cluster Resources collector uses from `pkg/collect` for usage in the APIs - https://github.com/replicatedhq/sbctl/blob/main/pkg/api/server.go#L220. This is an example of the way we can start making the sbctl code more efficient with this change.
|
||||
|
||||
cluster_resources.go
|
||||
```go
|
||||
const ClusterResourcesPath = `cluster-resources`
|
||||
...
|
||||
|
||||
path := filepath.Join(ClusterResourcesPath, "namespaces.json")
|
||||
output.SaveResult(c.BundlePath, path, bytes.NewBuffer(namespaces))
|
||||
```
|
||||
|
||||
sbctl-server.go
|
||||
```go
|
||||
import (
|
||||
...
|
||||
"github.com/replicatedhq/troubleshoot/pkg/collect"
|
||||
...
|
||||
)
|
||||
...
|
||||
|
||||
dirName := filepath.Join(collect.ClusterResourcesPath, fmt.Sprintf("%s", resource))
|
||||
```
|
||||
|
||||
### Package Structure
|
||||
```
|
||||
cmd
|
||||
serve/
|
||||
shell/
|
||||
pkg
|
||||
serve/
|
||||
shell/
|
||||
tests # API tests, integration tests etc reside here.
|
||||
serve/ # sbctl BDD tests.
|
||||
# all tests and test fixtures moved here
|
||||
```
|
||||
|
||||
### Makefile Changes
|
||||
|
||||
We'll need to add make targets specific to these commands similar to the current ones
|
||||
```
|
||||
make serve run-serve
|
||||
make shell run-shell
|
||||
make ginkgo
|
||||
```
|
||||
|
||||
### Docs
|
||||
In troubleshoot.sh docs, add a new sub section under "Support Bundle" describing then new serve & shell subcommands.
|
||||
|
||||
### Other Changes
|
||||
We would need to merge some of the support bundle functionality we see in both projects like so
|
||||
|
||||
- Create a new sbutil module to store reusable support bundle functionality. At least `analyze` & `serve` modules will depend on this module
|
||||
|
||||
```
|
||||
pkg
|
||||
sbutil/
|
||||
```
|
||||
|
||||
- Merge `troubleshoot/pkg/analyze/download.ExtractTroubleshootBundle` & `sbctl/pkg/sbctl/support-bundle.ExtractBundle` that duplicate support bundle archive extraction
|
||||
- Build on `sbctl/pkg/sbctl/support-bundle.ClusterData` to have it expose well known paths (ClusterResourcesDir, Version files, analysis results etc) and unmarshalled resources (this bit can be built on a need to have basis) in a support bundle especially once [Add generic kubernetes resource analyzer #780 PR](https://github.com/replicatedhq/troubleshoot/pull/780) is merged.
|
||||
- Build on `sbctl/pkg/sbctl/support-bundle.FindClusterData` to perform pre-validation of a support bundle to ensure it is valid before running any applications.
|
||||
|
||||
## Limitations
|
||||
|
||||
## Assumptions
|
||||
|
||||
## Testing
|
||||
We will need to have a separate directory for sbctl (ginkgo BDD) tests. The test harness used is ginkgo cli instead of go test and there is no straight forward way of separating these tests. Also, from a directory structure point of view, such integration tests usually reside in modules in a root level tests directory. Changes to the test code need to be minimal, ideally no change, cause they will be used to ensure any refactored code does not break. We could now easily introduce tests which ensure that changes to collectors don't break APIs in sbctl.
|
||||
|
||||
## Alternatives Considered
|
||||
* Have troubleshoot as a library dependency in sbctl keeping it as a separate binary and repo
|
||||
* Move sbctl to the Troubleshoot library "as is" and continue maintaing a separate binary
|
||||
* Leave things as they are
|
||||
|
||||
## Security Considerations
|
||||
@@ -0,0 +1,74 @@
|
||||
# Provide an extendable API for accessing bundle information
|
||||
|
||||
## Goals
|
||||
|
||||
* Provide API based access to collected information, decoupling other projects from troubleshoot on-disk format
|
||||
* Reuse existing APIs when they exist to make the bundle compatible with existing tools without modification
|
||||
* Plan for extensibility for accessing information beyond just the standard kubernetes api
|
||||
|
||||
## Non Goals
|
||||
|
||||
* Compatibility with previous on-disk formats
|
||||
* Compatibility with existing collectors without modification
|
||||
* There should be a plan to allow the implementation of existing collectors
|
||||
|
||||
## Background
|
||||
|
||||
While using the information gathered in a support bundle users were finding it hard to find information while manually reviewing the various files collected in the bundle. Users have to understand the folder structure, files structure, and process JSON files to find information about the cluster. The [sbctl](https://github.com/replicatedhq/sbctl) project was created to prove out the utility of providing api based access so that users could use existing tools which they already understood. This has been a very successful experiment with feedback being that most users now use this utility as their primary, or only, interface to the support bundle information.
|
||||
|
||||
There are some drawbacks to the current approach. The `sbctl` project is tightly coupled to troubleshoot on-disk formats, each kubernetes API must be implemented in `sbctl` individually and will require being kept up to date as APIs change, and `sbctl` has no plan today to provide similar API based access to information other than the standard kubernetes api.
|
||||
|
||||
This proposal is meant to take the learnings from `sbctl` and consider implementing it as a first class feature of troubleshoot while attempting to address the current maintenance and expandability limitations.
|
||||
|
||||
## High-Level Design
|
||||
|
||||
To help address standard access to API data, troubleshoot will start an etcd instance which collectors can then use to store collected information rather than writing to custom on-disk locations. Collectors that only need to collect Kubernetes API information then do not need to serve up data as the API server will be used to provide access to the collected data. Storing data directly in etcd will allow troubleshoot to later serve up this same information by again starting an api-server and etcd using the previously collected etcd data store. This should remove almost all maintenance from troubleshoot for implementing API calls to access the collected information.
|
||||
|
||||
There will also be information that is desired to be stored that doesn't have any native representation in the api-server today. Examples could include custom collectors which execute into containers and extensions like [metrics server](https://github.com/kubernetes-sigs/metrics-server). These components can be addressed using the built in [Kubernetes API Aggregation Layer](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/apiserver-aggregation/) which is how `metrics server` itself works to extend and provide api based access to node information. By registering additional API extensions troubleshoot plugins can implement both a collection and an API for retrieving custom information which is accessible in the same fashion as the rest of the api-server.
|
||||
|
||||
The additional benefit to this, which can be demonstrated with `metrics-server`, is that collectors can be written for any other extension API and be compatible with existing tools the same way using the api-server provides compatibility with `kubectl`. Using `metrics-server` as an example, a collector can be written to collect node information which can be stored locally. The collector can then implement the standard [GET Endpoints](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/apiserver-aggregation/) from the metrics-server and reply to them with the results it collected. By doing so, all tools that work with metrics-server today, like `kubectl top` will also work with information served from a support bundle. Additionally, the collector implementation handles any custom file formats without exposing that to any other tool making it easy to maintain.
|
||||
|
||||
Any other access to the filesystem directly will be modified to instead use the provided api-server. This means analyzers will not directly reference files on disk and will instead run against the api-server to analyze the collected information. This decouples analyzers from how collectors store data providing clean separation of concerns for maintaining both collectors and analyzers. Decoupling these also creates a natural way to implement analyzers that use data from multiple collectors. This could also allow analyzers to run against existing clusters providing a use for analyzers independent of support bundle collection. This could encourage additional community contributions of analyzers.
|
||||
|
||||
An initially unintended benefit of using the Aggregation Layer is that any HostCollector using this implementation would be very close to an implementation of an extension which you could install in clusters. This could make HostCollectors also useful to install as a service in a live cluster for operations information about hosts.
|
||||
|
||||
## Detailed Design
|
||||
|
||||
### Outstanding design questions
|
||||
|
||||
1. How reasonable is it to start an api-server as part of troubleshoot? Consider the following known implementations that do something like this:
|
||||
|
||||
* [envtest](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/envtest) - requires binaries present on the machine
|
||||
* [microk8s implementation](https://github.com/canonical/microk8s/blob/master/build-scripts/patches/0000-Kubelite-integration.patch) - bundles slightly modified binaries
|
||||
* [k0s uses upstream binaries statically compiled](https://docs.k0sproject.io/v1.23.8+k0s.0/architecture/) - bundles statically compiled binaries that self extract and uses a process monitor to run them
|
||||
|
||||
2. Can you in fact push metadat like "Status" into an api-server or do we have to write directly to etcd?
|
||||
|
||||
* If we can't push to the api-server is just writing the information directly into etcd something we can do and have a reasonable expectation of compatibility?
|
||||
|
||||
3. Is the overhead to write an Aggregation API going to add an unnecessary burden to writing new collector plugins? Can these be templated into a reasonably to ease collector creation?
|
||||
|
||||
## Limitations
|
||||
|
||||
Using the actual API server will provide limitations on the version skew which can be collected/displayed. This could be addressed by including multiple versions of the kubernetes-api server to allow serving a wide range of support bundles. This limitation likely already exists today but would exist in the tooling that is trying to collect, analyzer, or server the data.
|
||||
|
||||
## Assumptions
|
||||
|
||||
* Serving logs hasn't been designed yet, and presumably can be addressed in the detailed design to provide logs to the api-server in place of kubelet. Ideally this can be done using the standard upstream kubernetes-api server it is undesirable to fork it.
|
||||
* Running the api-server, etcd, and any other supporting services (like kubelet) as go routines while adding some overhead to the collection process won't cause a significant burden on ram or cpu to collect support bundles.
|
||||
|
||||
## Testing
|
||||
|
||||
## Alternatives Considered
|
||||
|
||||
### Keep sbctl separate
|
||||
|
||||
The current `sbctl` project could be left to run it's course independent of this project. This leaves the troubleshoot project reliant on a separate project to provide a good user experience for anything other than analyzers.
|
||||
|
||||
## Security Considerations
|
||||
|
||||
Consideration to how Redactors are implemented needs to be considered.
|
||||
|
||||
## References
|
||||
|
||||
Original PR discussion found [here](https://github.com/replicatedhq/troubleshoot/pull/611)
|
||||
@@ -0,0 +1,95 @@
|
||||
# Provide a facility to automatically obtain updated specs
|
||||
|
||||
## Background
|
||||
|
||||
Troubleshoot is limited in that when folks write an update or a new spec for data collection and analysis, that upgrade is not available when Troubleshoot is invoked if specs for it are stored in a secret or a file which was deployed by an application. Updating the local spec is simple enough, but may require an upgrade to the application (e.g. KOTS) in order to collect updates to the spec supplied by that application. This update requirement delays folks from accessing updated Troubleshoot specs and therefore discourages people from writing new/updated specs.
|
||||
|
||||
## Goals
|
||||
|
||||
* Provide a means for a spec to optionally specify a location for a spec that can replace it if successfully reached.
|
||||
|
||||
## Other requirements
|
||||
|
||||
* Maintain the ability for Troubleshoot to run in an airgapped environment, though with some feature limitations.
|
||||
* Maintain compatilbility with existing Troubleshoot specs.
|
||||
|
||||
## High-Level Design
|
||||
|
||||
Add a new field to the Troubleshoot spec definition, which includes a URI used to locate a replacement spec.
|
||||
|
||||
If the field is populated, Troubleshoot is to attempt to collect the spec from the location provided, and if successful, ignore the remainder of the spec provided and use the spec listed in the new field.
|
||||
|
||||
If the additional spec is not found at the location (or, if there is no network access to that location), Troubleshoot is to continue processing the remainder of the spec provided, with a log message describing the failure to process the URI.
|
||||
|
||||
Add a CLI flag (e.g. `--no-updates`) to disable the URI specified location from being accessed. This would be useful in airgap environments and/or when we simply do not want to have the external spec used, without having to update the yaml, secret, or remote source.
|
||||
|
||||
URI's provided may be any of the URI types already accepted by Troubleshoot, including web addresses (https://), secrets, or files.
|
||||
|
||||
## Detailed Design
|
||||
|
||||
Current spec format is like this example:
|
||||
|
||||
```yaml
|
||||
apiVersion: troubleshoot.sh/v1beta2
|
||||
kind: SupportBundle
|
||||
metadata:
|
||||
name: default
|
||||
spec:
|
||||
collectors:
|
||||
- clusterInfo: {}
|
||||
- clusterResources: {}
|
||||
analyzers:
|
||||
- cephStatus: {}
|
||||
- longhorn: {}
|
||||
```
|
||||
|
||||
We could add a new type, `specURI`, which contains one or more URIs from which to obtain specs. If the spec is retrieved successfully then the remainder of the provided spec is ignored, and replaced with the one downloaded:
|
||||
|
||||
```yaml
|
||||
apiVersion: troubleshoot.sh/v1beta2
|
||||
kind: SupportBundle
|
||||
metadata:
|
||||
name: default
|
||||
spec:
|
||||
uri: https://raw.githubusercontent.com/replicatedhq/troubleshoot-specs/main/in-cluster/default.yaml
|
||||
collectors:
|
||||
- clusterInfo: {}
|
||||
- clusterResources: {}
|
||||
analyzers:
|
||||
- cephStatus: {}
|
||||
- longhorn: {}
|
||||
```
|
||||
|
||||
When a spec is parsed from the initial call to Troubleshoot, the content should be read and if a `specURI` exists which is not blank, the code should attempt to download that URI. Should that be successful, the collectors and analyzers sections of the downloaded content should be used to replace the remainder of the spec provided via the initial call.
|
||||
|
||||
## Impact on kURL and KOTS
|
||||
|
||||
This section is included because KOTS is a significant consumer of the Troubleshoot codebase, and as such deserves consideration when significant changes are made.
|
||||
|
||||
The code changes proposed in this document do not require any changes to kURL or KOTS, and any changes to those repos are excluded from the scope of work described here. The following notes are suggestions for how the kURL and KOTS repos could benefit from the changes in this document, and could relate to any project which calls Troubleshoot or includes Troubleshoot specs.
|
||||
|
||||
For kURL, each component/addon installed could include adding an individual spec with a URI pointing at a specific spec for that component, which could be updated independently of other components. Invoking troubleshoot with all the individual specs required would allow updated specs to be collected without needing to upgrade any particular component in the cluster.
|
||||
|
||||
KOTS currently provides a spec to Troubleshoot which is a merge of a default spec provided by the KOTS codebase, and the spec provided by an application vendor. Should either of those provide a URI, that would mean the downloaded spec would replace the entire spec. This is undesirable since the URI would need to contain the application vendor's updated spec as well as the generic cluster-wide collectors and analyzers, which is a significant maintenance challenge. To resolve this, it is desirable that the following is completed before KOTS uses the URI field:
|
||||
|
||||
* Troubleshoot should accept multiple specs (see #650)
|
||||
* KOTS would need to be modified to provide the application vendor and the default specs independently of one another.
|
||||
|
||||
## Limitations
|
||||
|
||||
Redactors are currently excluded from this proposal, though it would be desirable to add a similar feature in the future.
|
||||
|
||||
If a URI provided includes a spec which includes another URI, it is possible to get into some kind of recursion if the downloaded spec contains another URI. For this reason, and to ensure that the results are predictable, we should only parse the URI field once per spec for specs passed to Troubleshoot on initiation via the CLI or entrypoint.
|
||||
|
||||
## Assumptions
|
||||
|
||||
## Testing
|
||||
|
||||
## Alternatives Considered
|
||||
|
||||
* Some mechanism to trigger a process to update secrets stored in Kubernetes. This was rejected due to the need to run a manual update spec for something installed in the cluster.
|
||||
* Altering KOTS to provide a URL for the spec rather than storing it in code. This was rejected to allow airgap compatibility.
|
||||
|
||||
## Security Considerations
|
||||
|
||||
This change will make additional network calls with default usage of Troubleshoot. To ensure a user has control of limiting these calls an argument to disable this feature entirely will be provided. This allows users with different security postures to select what's appropriate for their environment.
|
||||
@@ -0,0 +1,21 @@
|
||||
# Title
|
||||
|
||||
## Goals
|
||||
|
||||
## Non Goals
|
||||
|
||||
## Background
|
||||
|
||||
## High-Level Design
|
||||
|
||||
## Detailed Design
|
||||
|
||||
## Limitations
|
||||
|
||||
## Assumptions
|
||||
|
||||
## Testing
|
||||
|
||||
## Alternatives Considered
|
||||
|
||||
## Security Considerations
|
||||
@@ -0,0 +1,53 @@
|
||||
## preflight
|
||||
|
||||
Run and retrieve preflight checks in a cluster
|
||||
|
||||
### Synopsis
|
||||
|
||||
A preflight check is a set of validations that can and should be run to ensure
|
||||
that a cluster meets the requirements to run an application.
|
||||
|
||||
```
|
||||
preflight [url] [flags]
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
--as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
|
||||
--as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
|
||||
--as-uid string UID to impersonate for the operation.
|
||||
--cache-dir string Default cache directory (default "$HOME/.kube/cache")
|
||||
--certificate-authority string Path to a cert file for the certificate authority
|
||||
--client-certificate string Path to a client certificate file for TLS
|
||||
--client-key string Path to a client key file for TLS
|
||||
--cluster string The name of the kubeconfig cluster to use
|
||||
--collect-without-permissions always run preflight checks even if some require permissions that preflight does not have (default true)
|
||||
--collector-image string the full name of the collector image to use
|
||||
--collector-pullpolicy string the pull policy of the collector image
|
||||
--context string The name of the kubeconfig context to use
|
||||
--cpuprofile string File path to write cpu profiling data
|
||||
--debug enable debug logging
|
||||
--format string output format, one of human, json, yaml. only used when interactive is set to false (default "human")
|
||||
-h, --help help for preflight
|
||||
--insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
|
||||
--interactive interactive preflights (default true)
|
||||
--kubeconfig string Path to the kubeconfig file to use for CLI requests.
|
||||
--memprofile string File path to write memory profiling data
|
||||
-n, --namespace string If present, the namespace scope for this CLI request
|
||||
-o, --output string specify the output file path for the preflight checks
|
||||
--request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
|
||||
--selector string selector (label query) to filter remote collection nodes on.
|
||||
-s, --server string The address and port of the Kubernetes API server
|
||||
--since string force pod logs collectors to return logs newer than a relative duration like 5s, 2m, or 3h.
|
||||
--since-time string force pod logs collectors to return logs after a specific date (RFC3339)
|
||||
--tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
|
||||
--token string Bearer token for authentication to the API server
|
||||
--user string The name of the kubeconfig user to use
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [preflight version](preflight_version.md) - Print the current version and exit
|
||||
|
||||
###### Auto generated by spf13/cobra on 3-Jan-2023
|
||||
@@ -0,0 +1,40 @@
|
||||
## preflight version
|
||||
|
||||
Print the current version and exit
|
||||
|
||||
### Synopsis
|
||||
|
||||
Print the current version and exit
|
||||
|
||||
```
|
||||
preflight version [flags]
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for version
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--collect-without-permissions always run preflight checks even if some require permissions that preflight does not have (default true)
|
||||
--collector-image string the full name of the collector image to use
|
||||
--collector-pullpolicy string the pull policy of the collector image
|
||||
--cpuprofile string File path to write cpu profiling data
|
||||
--debug enable debug logging
|
||||
--format string output format, one of human, json, yaml. only used when interactive is set to false (default "human")
|
||||
--interactive interactive preflights (default true)
|
||||
--memprofile string File path to write memory profiling data
|
||||
-o, --output string specify the output file path for the preflight checks
|
||||
--selector string selector (label query) to filter remote collection nodes on.
|
||||
--since string force pod logs collectors to return logs newer than a relative duration like 5s, 2m, or 3h.
|
||||
--since-time string force pod logs collectors to return logs after a specific date (RFC3339)
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [preflight](preflight.md) - Run and retrieve preflight checks in a cluster
|
||||
|
||||
###### Auto generated by spf13/cobra on 3-Jan-2023
|
||||
@@ -0,0 +1,56 @@
|
||||
## support-bundle
|
||||
|
||||
Generate a support bundle
|
||||
|
||||
### Synopsis
|
||||
|
||||
A support bundle is an archive of files, output, metrics and state
|
||||
from a server that can be used to assist when troubleshooting a Kubernetes cluster.
|
||||
|
||||
```
|
||||
support-bundle [urls...] [flags]
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
--as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
|
||||
--as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
|
||||
--as-uid string UID to impersonate for the operation.
|
||||
--cache-dir string Default cache directory (default "$HOME/.kube/cache")
|
||||
--certificate-authority string Path to a cert file for the certificate authority
|
||||
--client-certificate string Path to a client certificate file for TLS
|
||||
--client-key string Path to a client key file for TLS
|
||||
--cluster string The name of the kubeconfig cluster to use
|
||||
--collect-without-permissions always generate a support bundle, even if it some require additional permissions (default true)
|
||||
--context string The name of the kubeconfig context to use
|
||||
--cpuprofile string File path to write cpu profiling data
|
||||
--debug enable debug logging
|
||||
-h, --help help for support-bundle
|
||||
--insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
|
||||
--interactive enable/disable interactive mode (default true)
|
||||
--kubeconfig string Path to the kubeconfig file to use for CLI requests.
|
||||
--load-cluster-specs enable/disable loading additional troubleshoot specs found within the cluster. required when no specs are provided on the command line
|
||||
--memprofile string File path to write memory profiling data
|
||||
-n, --namespace string If present, the namespace scope for this CLI request
|
||||
--no-uri When this flag is used, Troubleshoot does not attempt to retrieve the bundle referenced by the uri: field in the spec.`
|
||||
-o, --output string specify the output file path for the support bundle
|
||||
--redact enable/disable default redactions (default true)
|
||||
--redactors strings names of the additional redactors to use
|
||||
--request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
|
||||
-l, --selector strings selector to filter on for loading additional support bundle specs found in secrets within the cluster (default [troubleshoot.io/kind=support-bundle])
|
||||
-s, --server string The address and port of the Kubernetes API server
|
||||
--since string force pod logs collectors to return logs newer than a relative duration like 5s, 2m, or 3h.
|
||||
--since-time string force pod logs collectors to return logs after a specific date (RFC3339)
|
||||
--tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
|
||||
--token string Bearer token for authentication to the API server
|
||||
--user string The name of the kubeconfig user to use
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [support-bundle analyze](support-bundle_analyze.md) - analyze a support bundle
|
||||
* [support-bundle redact](support-bundle_redact.md) - Redact information from a generated support bundle archive
|
||||
* [support-bundle version](support-bundle_version.md) - Print the current version and exit
|
||||
|
||||
###### Auto generated by spf13/cobra on 3-Jan-2023
|
||||
@@ -0,0 +1,33 @@
|
||||
## support-bundle analyze
|
||||
|
||||
analyze a support bundle
|
||||
|
||||
### Synopsis
|
||||
|
||||
Analyze a support bundle using the Analyzer definitions provided
|
||||
|
||||
```
|
||||
support-bundle analyze [url] [flags]
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
--bundle string filename of the support bundle to analyze
|
||||
-h, --help help for analyze
|
||||
--output string output format: json, yaml
|
||||
--quiet enable/disable error messaging and only show parseable output
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--cpuprofile string File path to write cpu profiling data
|
||||
--memprofile string File path to write memory profiling data
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [support-bundle](support-bundle.md) - Generate a support bundle
|
||||
|
||||
###### Auto generated by spf13/cobra on 3-Jan-2023
|
||||
@@ -0,0 +1,42 @@
|
||||
## support-bundle redact
|
||||
|
||||
Redact information from a generated support bundle archive
|
||||
|
||||
### Synopsis
|
||||
|
||||
Redaction is the process of masking sensitive information from collected data in a support bundle.
|
||||
This is done using rules defined in the list of redactor manifests provided in the [urls...] command line
|
||||
argument. Default built in redactors will also be run, but these would have been run when the support
|
||||
bundle was generated. After redaction, the support bundle is archived once more. The resulting file will
|
||||
be stored in the current directory in the path provided by the --output flag.
|
||||
|
||||
The [urls...] argument is a list of either oci://.., http://.., https://.. or local paths to yaml files.
|
||||
|
||||
For more information on redactors visit https://troubleshoot.sh/docs/redact/
|
||||
|
||||
|
||||
```
|
||||
support-bundle redact [urls...] [flags]
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
--bundle string file path of the support bundle archive to redact
|
||||
-h, --help help for redact
|
||||
-o, --output string file path of where to save the redacted support bundle archive (default "redacted-support-bundle-YYYY-MM-DDTHH_MM_SS.tar.gz")
|
||||
-q, --quiet enable/disable error messaging and only show parseable output
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--cpuprofile string File path to write cpu profiling data
|
||||
--memprofile string File path to write memory profiling data
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [support-bundle](support-bundle.md) - Generate a support bundle
|
||||
|
||||
###### Auto generated by spf13/cobra on 3-Jan-2023
|
||||
@@ -0,0 +1,30 @@
|
||||
## support-bundle version
|
||||
|
||||
Print the current version and exit
|
||||
|
||||
### Synopsis
|
||||
|
||||
Print the current version and exit
|
||||
|
||||
```
|
||||
support-bundle version [flags]
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for version
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--cpuprofile string File path to write cpu profiling data
|
||||
--memprofile string File path to write memory profiling data
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [support-bundle](support-bundle.md) - Generate a support bundle
|
||||
|
||||
###### Auto generated by spf13/cobra on 3-Jan-2023
|
||||
@@ -1,9 +1,9 @@
|
||||
apiVersion: troubleshoot.sh/v1beta2
|
||||
kind: HostCollector
|
||||
metadata:
|
||||
name: modules
|
||||
name: port
|
||||
spec:
|
||||
collectors:
|
||||
- cpu: {}
|
||||
- memory: {}
|
||||
# - kernelModules: {}
|
||||
- udpPortStatus:
|
||||
collectorName: flannel
|
||||
port: 8472
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: troubleshoot.sh/v1beta2
|
||||
kind: HostCollector
|
||||
metadata:
|
||||
name: port
|
||||
spec:
|
||||
collectors:
|
||||
- udpPortStatus:
|
||||
collectorName: flannel
|
||||
port: 8472
|
||||
@@ -0,0 +1,98 @@
|
||||
apiVersion: troubleshoot.sh/v1beta2
|
||||
kind: Preflight
|
||||
metadata:
|
||||
name: example
|
||||
spec:
|
||||
collectors:
|
||||
- data:
|
||||
name: config/replicas.txt
|
||||
data: "5"
|
||||
- run:
|
||||
collectorName: "static-hi"
|
||||
image: 'alpine:3'
|
||||
command: ["echo", "hi static!"]
|
||||
analyzers:
|
||||
- clusterVersion:
|
||||
outcomes:
|
||||
- fail:
|
||||
when: "< 1.13.0"
|
||||
message: This application requires at least Kubernetes 1.13.0 or later, and recommends 1.15.0.
|
||||
uri: https://www.kubernetes.io
|
||||
- warn:
|
||||
when: "< 1.15.0"
|
||||
message: Your cluster meets the minimum version of Kubernetes, but we recommend you update to 1.15.0 or later.
|
||||
uri: https://kubernetes.io
|
||||
- pass:
|
||||
when: ">= 1.15.0"
|
||||
message: Your cluster meets the recommended and required versions of Kubernetes.
|
||||
- distribution:
|
||||
outcomes:
|
||||
- pass:
|
||||
when: "== k3s"
|
||||
message: K3S is a supported distribution
|
||||
- warn:
|
||||
message: Unable to determine the distribution of Kubernetes
|
||||
- textAnalyze:
|
||||
checkName: Replica Count
|
||||
fileName: config/replicas.txt
|
||||
regexGroups: '(?P<Replicas>\d+)'
|
||||
outcomes:
|
||||
- fail:
|
||||
when: "Replicas < 5"
|
||||
message: That's not enough replicas!
|
||||
- pass:
|
||||
message: You have at least 5 replicas
|
||||
- textAnalyze:
|
||||
checkName: Said hi!
|
||||
fileName: /static-hi.log
|
||||
regex: 'hi static'
|
||||
outcomes:
|
||||
- fail:
|
||||
message: Didn't say hi.
|
||||
- pass:
|
||||
message: Said hi!
|
||||
- nodeResources:
|
||||
checkName: Must be exactly 1 node in the cluster
|
||||
outcomes:
|
||||
- pass:
|
||||
when: "= 1"
|
||||
message: This cluster has exactly 1 node
|
||||
- fail:
|
||||
message: This application requires exactly 1 node
|
||||
- nodeResources:
|
||||
checkName: Must have 1 node with at least 2 cores
|
||||
filters:
|
||||
cpuCapacity: "2"
|
||||
outcomes:
|
||||
- pass:
|
||||
when: "= 1"
|
||||
message: This cluster has exactly 1 node with at least 2 cores
|
||||
- fail:
|
||||
message: This application requires exactly 1 node with at least 2 cores
|
||||
- nodeResources:
|
||||
checkName: Must have 1 node with 2Gi (available) memory and at least 2 cores (on a single node)
|
||||
filters:
|
||||
allocatableMemory: 2Gi
|
||||
cpuCapacity: "2"
|
||||
outcomes:
|
||||
- pass:
|
||||
when: "= 1"
|
||||
message: This cluster has exactly 1 node with at least 2Gi available memory and 2 cores
|
||||
- fail:
|
||||
message: This application requires exactly 1 node with at least 2Gi available memory and 2 cores
|
||||
- nodeResources:
|
||||
checkName: There must be exactly 1 node in the cluster
|
||||
outcomes:
|
||||
- pass:
|
||||
when: "count() = 1"
|
||||
message: This has exactly 1 node in the cluster
|
||||
- fail:
|
||||
message: This application requires exactly 1 node in the cluster
|
||||
- nodeResources:
|
||||
checkName: There must be a total of at least 2Gi of memory on all nodes
|
||||
outcomes:
|
||||
- fail:
|
||||
when: "sum(memoryCapacity) < 2Gi"
|
||||
message: This application requires that 2Gi or more memory be available to the cluster
|
||||
- pass:
|
||||
message: This cluster has sufficient memory
|
||||
@@ -0,0 +1,19 @@
|
||||
apiVersion: troubleshoot.sh/v1beta2
|
||||
kind: HostPreflight
|
||||
metadata:
|
||||
name: subnet-available
|
||||
spec:
|
||||
collectors:
|
||||
# would output yes/no depending if there is a /22 available in 10.0.0.0/8
|
||||
- subnetAvailable:
|
||||
CIDRRangeAlloc: "10.0.0.0/8"
|
||||
desiredCIDR: 22
|
||||
analyzers:
|
||||
- subnetAvailable:
|
||||
outcomes:
|
||||
- fail:
|
||||
when: "no-subnet-available"
|
||||
message: failed to find available subnet
|
||||
- pass:
|
||||
when: "a-subnet-is-available"
|
||||
message: available /22 subnet found
|
||||
@@ -0,0 +1,64 @@
|
||||
apiVersion: troubleshoot.sh/v1beta2
|
||||
kind: HostPreflight
|
||||
metadata:
|
||||
name: packages
|
||||
spec:
|
||||
collectors:
|
||||
- systemPackages:
|
||||
ubuntu:
|
||||
- open-iscsi
|
||||
ubuntu16:
|
||||
- nfs-common
|
||||
ubuntu18:
|
||||
- nmap
|
||||
ubuntu20:
|
||||
- nmap
|
||||
- nfs-common
|
||||
rhel:
|
||||
- iscsi-initiator-utils
|
||||
rhel7:
|
||||
- libzstd
|
||||
rhel8:
|
||||
- nfs-utils
|
||||
- openssl
|
||||
rhel9:
|
||||
- nfs-utils
|
||||
- openssl
|
||||
rocky8:
|
||||
- nfs-utils
|
||||
- openssl
|
||||
rocky9:
|
||||
- nfs-utils
|
||||
- openssl
|
||||
centos:
|
||||
- iscsi-initiator-utils
|
||||
centos7:
|
||||
- libzstd
|
||||
centos8:
|
||||
- nfs-utils
|
||||
- openssl
|
||||
centos9:
|
||||
- nfs-utils
|
||||
- openssl
|
||||
ol:
|
||||
- lvm2
|
||||
ol7:
|
||||
- libzstd
|
||||
- openssl
|
||||
ol8:
|
||||
- nfs-utils
|
||||
ol9:
|
||||
- nfs-utils
|
||||
amzn:
|
||||
- libzstd
|
||||
amzn2:
|
||||
- nfs-utils
|
||||
- openssl
|
||||
analyzers:
|
||||
- systemPackages:
|
||||
outcomes:
|
||||
- fail:
|
||||
when: "{{ not .IsInstalled }}"
|
||||
message: Package {{ .Name }} is not installed.
|
||||
- pass:
|
||||
message: Package {{ .Name }} is installed.
|
||||
@@ -0,0 +1,24 @@
|
||||
apiVersion: troubleshoot.sh/v1beta2
|
||||
kind: HostPreflight
|
||||
metadata:
|
||||
name: port
|
||||
spec:
|
||||
collectors:
|
||||
- udpPortStatus:
|
||||
collectorName: flannel
|
||||
port: 8472
|
||||
analyzers:
|
||||
- udpPortStatus:
|
||||
collectorName: flannel
|
||||
outcomes:
|
||||
- fail:
|
||||
when: "address-in-use"
|
||||
message: Another process was already listening on port 8472.
|
||||
- fail:
|
||||
when: "error"
|
||||
message: Unexpected port status
|
||||
- pass:
|
||||
when: "connected"
|
||||
message: Port 8472 is open
|
||||
- warn:
|
||||
message: Unexpected port status
|
||||
@@ -0,0 +1,70 @@
|
||||
apiVersion: troubleshoot.sh/v1beta2
|
||||
kind: Preflight
|
||||
metadata:
|
||||
name: sample
|
||||
spec:
|
||||
collectors:
|
||||
- mssql:
|
||||
collectorName: mssql
|
||||
uri: sqlserver://SA:nac3lle-ch@stise-bOMBay-wag@db.lab.shortrib.net:1433/master
|
||||
analyzers:
|
||||
- mssql:
|
||||
checkName: Must be SQLServer 15.x or later
|
||||
collectorName: mssql
|
||||
outcomes:
|
||||
- fail:
|
||||
when: "connected == false"
|
||||
message: Cannot connect to SQLServer
|
||||
- fail:
|
||||
when: "version < 15.x"
|
||||
message: The SQLServer must be at least version 15
|
||||
- pass:
|
||||
message: The SQLServer connection checks out
|
||||
- mssql:
|
||||
checkName: Must be SQLServer 14 or earlier
|
||||
collectorName: mssql
|
||||
outcomes:
|
||||
- fail:
|
||||
when: "connected == false"
|
||||
message: Cannot connect to SQLServer
|
||||
- fail:
|
||||
when: "version > 14.x"
|
||||
message: The SQLServer must be at most version 14
|
||||
- pass:
|
||||
message: The SQLServer connection checks out
|
||||
- mssql:
|
||||
checkName: Must be SQLServer 15.0.2000.1565
|
||||
collectorName: mssql
|
||||
outcomes:
|
||||
- fail:
|
||||
when: "connected == false"
|
||||
message: Cannot connect to SQLServer
|
||||
- fail:
|
||||
when: "version == 15.0.2000.1565"
|
||||
message: The SQLServer must be version 15.0.2000.1565
|
||||
- pass:
|
||||
message: The SQLServer connection checks out
|
||||
- mssql:
|
||||
checkName: Must not be SQLServer 15.0.2000.1565
|
||||
collectorName: mssql
|
||||
outcomes:
|
||||
- fail:
|
||||
when: "connected == false"
|
||||
message: Cannot connect to SQLServer
|
||||
- fail:
|
||||
when: "version != 15.0.2000.1565"
|
||||
message: The SQLServer must not be version 15.0.2000.1565
|
||||
- pass:
|
||||
message: The SQLServer connection checks out
|
||||
- mssql:
|
||||
checkName: I don't want to connect to your SQL Server
|
||||
collectorName: mssql
|
||||
outcomes:
|
||||
- fail:
|
||||
when: "connected == true"
|
||||
message: Can connect to your SQL Server
|
||||
- fail:
|
||||
when: "version != 15.0.2000.1565"
|
||||
message: The SQLServer must be version 15.0.2000.1565
|
||||
- pass:
|
||||
message: The SQLServer connection checks out
|
||||
@@ -16,20 +16,20 @@ spec:
|
||||
- pass:
|
||||
message: This cluster has enough nodes.
|
||||
- nodeResources:
|
||||
checkName: Must have 3 nodes with at least 6 cores
|
||||
checkName: Must have 3 nodes with at least 6 cores each
|
||||
filters:
|
||||
cpuCapacity: "6"
|
||||
outcomes:
|
||||
- fail:
|
||||
when: "< 3"
|
||||
when: "count() < 3"
|
||||
message: This application requires at least 3 nodes with 6 cores each
|
||||
- pass:
|
||||
message: This cluster has enough nodes with enough codes
|
||||
message: This cluster has enough nodes with enough cores
|
||||
- nodeResources:
|
||||
checkName: Must have 1 node with 16 GB (available) memory and 5 cores (on a single node)
|
||||
checkName: Must have 1 node with 16 GB (available) memory and 10 cores (on a single node)
|
||||
filters:
|
||||
allocatableMemory: 16Gi
|
||||
cpuCapacity: "5"
|
||||
cpuCapacity: "10"
|
||||
outcomes:
|
||||
- fail:
|
||||
when: "< 1"
|
||||
@@ -37,13 +37,32 @@ spec:
|
||||
- pass:
|
||||
message: This cluster has a node with enough memory.
|
||||
- nodeResources:
|
||||
checkName: There must be at least 3 nodes in the cluster
|
||||
checkName: Must have 1 node with 16 GB (available) memory and 4 cores of amd64 arch (on a single node)
|
||||
filters:
|
||||
allocatableMemory: 16Gi
|
||||
cpuArchitecture: amd64
|
||||
cpuCapacity: "4"
|
||||
outcomes:
|
||||
- fail:
|
||||
when: "count() < 3"
|
||||
message: This application requires at least 3 nodes in the cluster
|
||||
when: "< 1"
|
||||
message: This application requires at least 1 node with amd64 arch and 16GB available memory
|
||||
- pass:
|
||||
message: This cluster haas sufficient nodes
|
||||
message: This cluster has a node with the correct architecture and enough memory.
|
||||
- nodeResources:
|
||||
checkName: Must have 1 manager node with 16 GB (available) memory and 4 cores of amd64 arch
|
||||
filters:
|
||||
selector:
|
||||
matchLabel:
|
||||
node-role.kubernetes.io/master: ""
|
||||
allocatableMemory: 16Gi
|
||||
cpuArchitecture: amd64
|
||||
cpuCapacity: "6"
|
||||
outcomes:
|
||||
- fail:
|
||||
when: "< 1"
|
||||
message: This application requires at least 1 manager node with amd64 arch, 16GB available memory, and the label `node-role.kubernetes.io/master=""`
|
||||
- pass:
|
||||
message: This cluster has a node with the correct architecture and enough memory.
|
||||
- nodeResources:
|
||||
checkName: There must be a total of at least 32Gi of memory on all nodes
|
||||
outcomes:
|
||||
@@ -51,4 +70,14 @@ spec:
|
||||
when: "sum(memoryCapacity) < 32Gi"
|
||||
message: This application requires that 32Gi or more memory be available to the cluster
|
||||
- pass:
|
||||
message: This cluster haas sufficient memory
|
||||
message: This cluster has sufficient memory
|
||||
- nodeResources:
|
||||
checkName: There must be a total of at least 32Gi of memory on amd64 nodes
|
||||
filters:
|
||||
cpuArchitecture: amd64
|
||||
outcomes:
|
||||
- fail:
|
||||
when: "sum(memoryCapacity) < 32Gi"
|
||||
message: This application requires that 32Gi or more memory on amd64 nodes be available to the cluster
|
||||
- pass:
|
||||
message: This cluster has sufficient memory
|
||||
|
||||
@@ -20,4 +20,3 @@ spec:
|
||||
message: The postgres server must be at least version 10
|
||||
- pass:
|
||||
message: The postgres connection checks out
|
||||
|
||||
@@ -6,7 +6,9 @@ spec:
|
||||
collectors:
|
||||
- redis:
|
||||
collectorName: my-redis
|
||||
uri: rediss://default:password@hostname:6379
|
||||
uri: rediss://default:replicated@server:6380
|
||||
tls:
|
||||
skipVerify: true
|
||||
analyzers:
|
||||
- redis:
|
||||
checkName: Must be redis 5.x or later
|
||||
@@ -14,10 +16,9 @@ spec:
|
||||
outcomes:
|
||||
- fail:
|
||||
when: "connected == false"
|
||||
message: Cannot connect to postgres server
|
||||
message: Cannot connect to redis server
|
||||
- fail:
|
||||
when: "version < 5.0.0"
|
||||
message: The redis server must be at least version 5
|
||||
- pass:
|
||||
message: The redis connection checks out
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
apiVersion: troubleshoot.sh/v1beta2
|
||||
kind: HostPreflight
|
||||
metadata:
|
||||
name: port
|
||||
spec:
|
||||
collectors:
|
||||
- udpPortStatus:
|
||||
collectorName: flannel
|
||||
port: 8472
|
||||
analyzers:
|
||||
- udpPortStatus:
|
||||
collectorName: flannel
|
||||
outcomes:
|
||||
- fail:
|
||||
when: "address-in-use"
|
||||
message: Another process was already listening on port 8472.
|
||||
- fail:
|
||||
when: "error"
|
||||
message: Unexpected port status
|
||||
- pass:
|
||||
when: "connected"
|
||||
message: Port 8472 is open
|
||||
- warn:
|
||||
message: Unexpected port status
|
||||
@@ -7,15 +7,15 @@ spec:
|
||||
- clusterVersion:
|
||||
outcomes:
|
||||
- fail:
|
||||
when: "< 1.13.0"
|
||||
message: This application requires at least Kubernetes 1.13.0 or later, and recommends 1.15.0.
|
||||
when: "< 1.20.0"
|
||||
message: This application requires at least Kubernetes 1.20.0, and recommends 1.22.0.
|
||||
uri: https://www.kubernetes.io
|
||||
- warn:
|
||||
when: "< 1.15.0"
|
||||
message: Your cluster meets the minimum version of Kubernetes, but we recommend you update to 1.15.0 or later.
|
||||
when: "< 1.22.0"
|
||||
message: Your cluster meets the minimum version of Kubernetes, but we recommend you update to 1.22.0 or later.
|
||||
uri: https://kubernetes.io
|
||||
- pass:
|
||||
when: ">= 1.15.0"
|
||||
when: ">= 1.22.0"
|
||||
message: Your cluster meets the recommended and required versions of Kubernetes.
|
||||
- customResourceDefinition:
|
||||
checkName: Ingress
|
||||
@@ -28,10 +28,10 @@ spec:
|
||||
- containerRuntime:
|
||||
outcomes:
|
||||
- pass:
|
||||
when: "== docker"
|
||||
message: Docker container runtime was found.
|
||||
when: "== containerd"
|
||||
message: containerd container runtime was found.
|
||||
- fail:
|
||||
message: Did not find Docker container runtime.
|
||||
message: Did not find containerd container runtime.
|
||||
- storageClass:
|
||||
checkName: Required storage classes
|
||||
storageClassName: "default"
|
||||
@@ -88,11 +88,11 @@ spec:
|
||||
- pass:
|
||||
message: This cluster has enough nodes.
|
||||
- nodeResources:
|
||||
checkName: Every node in the cluster must have at least 10 GB of memory, with 32 GB recommended
|
||||
checkName: Every node in the cluster must have at least 8 GB of memory, with 32 GB recommended
|
||||
outcomes:
|
||||
- fail:
|
||||
when: "min(memoryCapacity) < 10Gi"
|
||||
message: All nodes must have at least 10 GB of memory.
|
||||
when: "min(memoryCapacity) < 8Gi"
|
||||
message: All nodes must have at least 8 GB of memory.
|
||||
uri: https://kurl.sh/docs/install-with-kurl/system-requirements
|
||||
- warn:
|
||||
when: "min(memoryCapacity) < 32Gi"
|
||||
@@ -121,4 +121,4 @@ spec:
|
||||
message: All nodes are recommended to have at least 100 GB of ephemeral storage.
|
||||
uri: https://kurl.sh/docs/install-with-kurl/system-requirements
|
||||
- pass:
|
||||
message: All nodes have at least 100 GB of ephemeral storage.
|
||||
message: All nodes have at least 100 GB of ephemeral storage.
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: troubleshoot.sh/v1beta2
|
||||
kind: Redactor
|
||||
metadata:
|
||||
name: e2e-redactor
|
||||
spec:
|
||||
redactors:
|
||||
- name: redact-static-text
|
||||
removals:
|
||||
values:
|
||||
- static
|
||||
@@ -0,0 +1,20 @@
|
||||
apiVersion: troubleshoot.sh/v1beta2
|
||||
kind: SupportBundle
|
||||
metadata:
|
||||
name: dbs-collector
|
||||
spec:
|
||||
collectors:
|
||||
- mysql:
|
||||
collectorName: mysql
|
||||
uri: 'root:my-secret-pw@tcp(localhost:3306)/mysql'
|
||||
parameters:
|
||||
- character_set_server
|
||||
- collation_server
|
||||
- init_connect
|
||||
- innodb_file_format
|
||||
- innodb_large_prefix
|
||||
- innodb_strict_mode
|
||||
- log_bin_trust_function_creators
|
||||
- redis:
|
||||
collectorName: my-redis
|
||||
uri: rediss://default:replicated@server:6380
|
||||
@@ -0,0 +1,103 @@
|
||||
apiVersion: troubleshoot.sh/v1beta2
|
||||
kind: SupportBundle
|
||||
metadata:
|
||||
name: example
|
||||
spec:
|
||||
collectors:
|
||||
- clusterInfo: {}
|
||||
- clusterResources: {}
|
||||
- data:
|
||||
name: config/replicas.txt
|
||||
data: "5"
|
||||
- runPod:
|
||||
collectorName: "static-hi"
|
||||
podSpec:
|
||||
containers:
|
||||
- name: static-hi
|
||||
image: alpine:3
|
||||
command: ["echo", "hi static!"]
|
||||
analyzers:
|
||||
- clusterVersion:
|
||||
outcomes:
|
||||
- fail:
|
||||
when: "< 1.20.0"
|
||||
message: This application requires at least Kubernetes 1.13.0 or later, and recommends 1.15.0.
|
||||
uri: https://www.kubernetes.io
|
||||
- warn:
|
||||
when: "< 1.21.0"
|
||||
message: Your cluster meets the minimum version of Kubernetes, but we recommend you update to 1.15.0 or later.
|
||||
uri: https://kubernetes.io
|
||||
- pass:
|
||||
when: ">= 1.22.0"
|
||||
message: Your cluster meets the recommended and required versions of Kubernetes.
|
||||
- distribution:
|
||||
outcomes:
|
||||
- pass:
|
||||
when: "== k3s"
|
||||
message: K3S is a supported distribution
|
||||
- warn:
|
||||
message: Unable to determine the distribution of Kubernetes
|
||||
- textAnalyze:
|
||||
checkName: Replica Count
|
||||
fileName: config/replicas.txt
|
||||
regexGroups: '(?P<Replicas>\d+)'
|
||||
outcomes:
|
||||
- fail:
|
||||
when: "Replicas < 5"
|
||||
message: That's not enough replicas!
|
||||
- pass:
|
||||
message: You have at least 5 replicas
|
||||
- textAnalyze:
|
||||
checkName: Said hi!
|
||||
fileName: /static-hi.log
|
||||
regex: 'hi static'
|
||||
outcomes:
|
||||
- fail:
|
||||
message: Didn't say hi.
|
||||
- pass:
|
||||
message: Said hi!
|
||||
- nodeResources:
|
||||
checkName: Must be exactly 1 node in the cluster
|
||||
outcomes:
|
||||
- pass:
|
||||
when: "= 1"
|
||||
message: This cluster has exactly 1 node
|
||||
- fail:
|
||||
message: This application requires exactly 1 node
|
||||
- nodeResources:
|
||||
checkName: Must have 1 node with at least 2 cores
|
||||
filters:
|
||||
cpuCapacity: "2"
|
||||
outcomes:
|
||||
- pass:
|
||||
when: "= 1"
|
||||
message: This cluster has exactly 1 node with at least 2 cores
|
||||
- fail:
|
||||
message: This application requires exactly 1 node with at least 2 cores
|
||||
- nodeResources:
|
||||
checkName: Must have 1 node with 2Gi (available) memory and at least 2 cores (on a single node)
|
||||
filters:
|
||||
allocatableMemory: 2Gi
|
||||
cpuCapacity: "2"
|
||||
outcomes:
|
||||
- pass:
|
||||
when: "= 1"
|
||||
message: This cluster has exactly 1 node with at least 2Gi available memory and 2 cores
|
||||
- fail:
|
||||
message: This application requires exactly 1 node with at least 2Gi available memory and 2 cores
|
||||
- nodeResources:
|
||||
checkName: There must be exactly 1 node in the cluster
|
||||
outcomes:
|
||||
- pass:
|
||||
when: "count() = 1"
|
||||
message: This has exactly 1 node in the cluster
|
||||
- fail:
|
||||
message: This application requires exactly 1 node in the cluster
|
||||
- nodeResources:
|
||||
checkName: There must be a total of at least 2Gi of memory on all nodes
|
||||
outcomes:
|
||||
- fail:
|
||||
when: "sum(memoryCapacity) < 2Gi"
|
||||
message: This application requires that 2Gi or more memory be available to the cluster
|
||||
- pass:
|
||||
message: This cluster has sufficient memory
|
||||
@@ -3,15 +3,28 @@ kind: SupportBundle
|
||||
metadata:
|
||||
name: example
|
||||
spec:
|
||||
hostCollectors:
|
||||
- hostOS: {}
|
||||
collectors:
|
||||
- logs:
|
||||
selector:
|
||||
- app=example
|
||||
- component=nginx
|
||||
namespace: repl{{ Namespace }}
|
||||
namespace: default
|
||||
limits:
|
||||
maxAge: 720h # 30*24
|
||||
maxLines: 10000
|
||||
maxBytes: 5000000
|
||||
- logs:
|
||||
collectorName: all-logs
|
||||
name: all-logs
|
||||
- runPod:
|
||||
collectorName: "static-hi"
|
||||
podSpec:
|
||||
containers:
|
||||
- name: static-hi
|
||||
image: alpine:3
|
||||
command: ["echo", "hi static!"]
|
||||
analyzers:
|
||||
- clusterVersion:
|
||||
outcomes:
|
||||
@@ -30,6 +43,7 @@ spec:
|
||||
outcomes:
|
||||
- fail:
|
||||
message: The Rook CRD was not found in the cluster.
|
||||
uri: https://kurl.sh/docs/add-ons/rook/some/path/that/does/not/exist/for/the/sake/of/having/a/very/long/url.md
|
||||
- pass:
|
||||
message: Rook is installed and available.
|
||||
- containerRuntime:
|
||||
@@ -99,3 +113,12 @@ spec:
|
||||
message: The API deployment has only a single ready replica.
|
||||
- pass:
|
||||
message: There are multiple replicas of the API deployment ready.
|
||||
- textAnalyze:
|
||||
checkName: Said hi!
|
||||
fileName: /static-hi.log
|
||||
regex: 'hi static'
|
||||
outcomes:
|
||||
- fail:
|
||||
message: Didn't say hi.
|
||||
- pass:
|
||||
message: Said hi!
|
||||
|
||||
@@ -1,110 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 Replicated, Inc..
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package troubleshootclientset
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1"
|
||||
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2"
|
||||
discovery "k8s.io/client-go/discovery"
|
||||
rest "k8s.io/client-go/rest"
|
||||
flowcontrol "k8s.io/client-go/util/flowcontrol"
|
||||
)
|
||||
|
||||
type Interface interface {
|
||||
Discovery() discovery.DiscoveryInterface
|
||||
TroubleshootV1beta1() troubleshootv1beta1.TroubleshootV1beta1Interface
|
||||
TroubleshootV1beta2() troubleshootv1beta2.TroubleshootV1beta2Interface
|
||||
}
|
||||
|
||||
// Clientset contains the clients for groups. Each group has exactly one
|
||||
// version included in a Clientset.
|
||||
type Clientset struct {
|
||||
*discovery.DiscoveryClient
|
||||
troubleshootV1beta1 *troubleshootv1beta1.TroubleshootV1beta1Client
|
||||
troubleshootV1beta2 *troubleshootv1beta2.TroubleshootV1beta2Client
|
||||
}
|
||||
|
||||
// TroubleshootV1beta1 retrieves the TroubleshootV1beta1Client
|
||||
func (c *Clientset) TroubleshootV1beta1() troubleshootv1beta1.TroubleshootV1beta1Interface {
|
||||
return c.troubleshootV1beta1
|
||||
}
|
||||
|
||||
// TroubleshootV1beta2 retrieves the TroubleshootV1beta2Client
|
||||
func (c *Clientset) TroubleshootV1beta2() troubleshootv1beta2.TroubleshootV1beta2Interface {
|
||||
return c.troubleshootV1beta2
|
||||
}
|
||||
|
||||
// Discovery retrieves the DiscoveryClient
|
||||
func (c *Clientset) Discovery() discovery.DiscoveryInterface {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.DiscoveryClient
|
||||
}
|
||||
|
||||
// NewForConfig creates a new Clientset for the given config.
|
||||
// If config's RateLimiter is not set and QPS and Burst are acceptable,
|
||||
// NewForConfig will generate a rate-limiter in configShallowCopy.
|
||||
func NewForConfig(c *rest.Config) (*Clientset, error) {
|
||||
configShallowCopy := *c
|
||||
if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 {
|
||||
if configShallowCopy.Burst <= 0 {
|
||||
return nil, fmt.Errorf("burst is required to be greater than 0 when RateLimiter is not set and QPS is set to greater than 0")
|
||||
}
|
||||
configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst)
|
||||
}
|
||||
var cs Clientset
|
||||
var err error
|
||||
cs.troubleshootV1beta1, err = troubleshootv1beta1.NewForConfig(&configShallowCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cs.troubleshootV1beta2, err = troubleshootv1beta2.NewForConfig(&configShallowCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfig(&configShallowCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &cs, nil
|
||||
}
|
||||
|
||||
// NewForConfigOrDie creates a new Clientset for the given config and
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *rest.Config) *Clientset {
|
||||
var cs Clientset
|
||||
cs.troubleshootV1beta1 = troubleshootv1beta1.NewForConfigOrDie(c)
|
||||
cs.troubleshootV1beta2 = troubleshootv1beta2.NewForConfigOrDie(c)
|
||||
|
||||
cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c)
|
||||
return &cs
|
||||
}
|
||||
|
||||
// New creates a new Clientset for the given RESTClient.
|
||||
func New(c rest.Interface) *Clientset {
|
||||
var cs Clientset
|
||||
cs.troubleshootV1beta1 = troubleshootv1beta1.New(c)
|
||||
cs.troubleshootV1beta2 = troubleshootv1beta2.New(c)
|
||||
|
||||
cs.DiscoveryClient = discovery.NewDiscoveryClient(c)
|
||||
return &cs
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 Replicated, Inc..
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
// This package has the automatically generated clientset.
|
||||
package troubleshootclientset
|
||||
-88
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 Replicated, Inc..
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
clientset "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset"
|
||||
troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1"
|
||||
faketroubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake"
|
||||
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2"
|
||||
faketroubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/discovery"
|
||||
fakediscovery "k8s.io/client-go/discovery/fake"
|
||||
"k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
// NewSimpleClientset returns a clientset that will respond with the provided objects.
|
||||
// It's backed by a very simple object tracker that processes creates, updates and deletions as-is,
|
||||
// without applying any validations and/or defaults. It shouldn't be considered a replacement
|
||||
// for a real clientset and is mostly useful in simple unit tests.
|
||||
func NewSimpleClientset(objects ...runtime.Object) *Clientset {
|
||||
o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder())
|
||||
for _, obj := range objects {
|
||||
if err := o.Add(obj); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
cs := &Clientset{tracker: o}
|
||||
cs.discovery = &fakediscovery.FakeDiscovery{Fake: &cs.Fake}
|
||||
cs.AddReactor("*", "*", testing.ObjectReaction(o))
|
||||
cs.AddWatchReactor("*", func(action testing.Action) (handled bool, ret watch.Interface, err error) {
|
||||
gvr := action.GetResource()
|
||||
ns := action.GetNamespace()
|
||||
watch, err := o.Watch(gvr, ns)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
return true, watch, nil
|
||||
})
|
||||
|
||||
return cs
|
||||
}
|
||||
|
||||
// Clientset implements clientset.Interface. Meant to be embedded into a
|
||||
// struct to get a default implementation. This makes faking out just the method
|
||||
// you want to test easier.
|
||||
type Clientset struct {
|
||||
testing.Fake
|
||||
discovery *fakediscovery.FakeDiscovery
|
||||
tracker testing.ObjectTracker
|
||||
}
|
||||
|
||||
func (c *Clientset) Discovery() discovery.DiscoveryInterface {
|
||||
return c.discovery
|
||||
}
|
||||
|
||||
func (c *Clientset) Tracker() testing.ObjectTracker {
|
||||
return c.tracker
|
||||
}
|
||||
|
||||
var _ clientset.Interface = &Clientset{}
|
||||
|
||||
// TroubleshootV1beta1 retrieves the TroubleshootV1beta1Client
|
||||
func (c *Clientset) TroubleshootV1beta1() troubleshootv1beta1.TroubleshootV1beta1Interface {
|
||||
return &faketroubleshootv1beta1.FakeTroubleshootV1beta1{Fake: &c.Fake}
|
||||
}
|
||||
|
||||
// TroubleshootV1beta2 retrieves the TroubleshootV1beta2Client
|
||||
func (c *Clientset) TroubleshootV1beta2() troubleshootv1beta2.TroubleshootV1beta2Interface {
|
||||
return &faketroubleshootv1beta2.FakeTroubleshootV1beta2{Fake: &c.Fake}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 Replicated, Inc..
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
// This package has the automatically generated fake clientset.
|
||||
package fake
|
||||
-57
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 Replicated, Inc..
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
|
||||
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
serializer "k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
)
|
||||
|
||||
var scheme = runtime.NewScheme()
|
||||
var codecs = serializer.NewCodecFactory(scheme)
|
||||
var parameterCodec = runtime.NewParameterCodec(scheme)
|
||||
var localSchemeBuilder = runtime.SchemeBuilder{
|
||||
troubleshootv1beta1.AddToScheme,
|
||||
troubleshootv1beta2.AddToScheme,
|
||||
}
|
||||
|
||||
// AddToScheme adds all types of this clientset into the given scheme. This allows composition
|
||||
// of clientsets, like in:
|
||||
//
|
||||
// import (
|
||||
// "k8s.io/client-go/kubernetes"
|
||||
// clientsetscheme "k8s.io/client-go/kubernetes/scheme"
|
||||
// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme"
|
||||
// )
|
||||
//
|
||||
// kclientset, _ := kubernetes.NewForConfig(c)
|
||||
// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme)
|
||||
//
|
||||
// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types
|
||||
// correctly.
|
||||
var AddToScheme = localSchemeBuilder.AddToScheme
|
||||
|
||||
func init() {
|
||||
v1.AddToGroupVersion(scheme, schema.GroupVersion{Version: "v1"})
|
||||
utilruntime.Must(AddToScheme(scheme))
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 Replicated, Inc..
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
// This package contains the scheme of the automatically generated clientset.
|
||||
package scheme
|
||||
-57
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 Replicated, Inc..
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package scheme
|
||||
|
||||
import (
|
||||
troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
|
||||
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
serializer "k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
)
|
||||
|
||||
var Scheme = runtime.NewScheme()
|
||||
var Codecs = serializer.NewCodecFactory(Scheme)
|
||||
var ParameterCodec = runtime.NewParameterCodec(Scheme)
|
||||
var localSchemeBuilder = runtime.SchemeBuilder{
|
||||
troubleshootv1beta1.AddToScheme,
|
||||
troubleshootv1beta2.AddToScheme,
|
||||
}
|
||||
|
||||
// AddToScheme adds all types of this clientset into the given scheme. This allows composition
|
||||
// of clientsets, like in:
|
||||
//
|
||||
// import (
|
||||
// "k8s.io/client-go/kubernetes"
|
||||
// clientsetscheme "k8s.io/client-go/kubernetes/scheme"
|
||||
// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme"
|
||||
// )
|
||||
//
|
||||
// kclientset, _ := kubernetes.NewForConfig(c)
|
||||
// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme)
|
||||
//
|
||||
// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types
|
||||
// correctly.
|
||||
var AddToScheme = localSchemeBuilder.AddToScheme
|
||||
|
||||
func init() {
|
||||
v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"})
|
||||
utilruntime.Must(AddToScheme(Scheme))
|
||||
}
|
||||
-194
@@ -1,194 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 Replicated, Inc..
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
v1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
|
||||
scheme "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/scheme"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
// AnalyzersGetter has a method to return a AnalyzerInterface.
|
||||
// A group's client should implement this interface.
|
||||
type AnalyzersGetter interface {
|
||||
Analyzers(namespace string) AnalyzerInterface
|
||||
}
|
||||
|
||||
// AnalyzerInterface has methods to work with Analyzer resources.
|
||||
type AnalyzerInterface interface {
|
||||
Create(ctx context.Context, analyzer *v1beta1.Analyzer, opts v1.CreateOptions) (*v1beta1.Analyzer, error)
|
||||
Update(ctx context.Context, analyzer *v1beta1.Analyzer, opts v1.UpdateOptions) (*v1beta1.Analyzer, error)
|
||||
UpdateStatus(ctx context.Context, analyzer *v1beta1.Analyzer, opts v1.UpdateOptions) (*v1beta1.Analyzer, error)
|
||||
Delete(ctx context.Context, name string, opts v1.DeleteOptions) error
|
||||
DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error
|
||||
Get(ctx context.Context, name string, opts v1.GetOptions) (*v1beta1.Analyzer, error)
|
||||
List(ctx context.Context, opts v1.ListOptions) (*v1beta1.AnalyzerList, error)
|
||||
Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error)
|
||||
Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.Analyzer, err error)
|
||||
AnalyzerExpansion
|
||||
}
|
||||
|
||||
// analyzers implements AnalyzerInterface
|
||||
type analyzers struct {
|
||||
client rest.Interface
|
||||
ns string
|
||||
}
|
||||
|
||||
// newAnalyzers returns a Analyzers
|
||||
func newAnalyzers(c *TroubleshootV1beta1Client, namespace string) *analyzers {
|
||||
return &analyzers{
|
||||
client: c.RESTClient(),
|
||||
ns: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
// Get takes name of the analyzer, and returns the corresponding analyzer object, and an error if there is any.
|
||||
func (c *analyzers) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.Analyzer, err error) {
|
||||
result = &v1beta1.Analyzer{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("analyzers").
|
||||
Name(name).
|
||||
VersionedParams(&options, scheme.ParameterCodec).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of Analyzers that match those selectors.
|
||||
func (c *analyzers) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.AnalyzerList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
result = &v1beta1.AnalyzerList{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("analyzers").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested analyzers.
|
||||
func (c *analyzers) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
opts.Watch = true
|
||||
return c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("analyzers").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Watch(ctx)
|
||||
}
|
||||
|
||||
// Create takes the representation of a analyzer and creates it. Returns the server's representation of the analyzer, and an error, if there is any.
|
||||
func (c *analyzers) Create(ctx context.Context, analyzer *v1beta1.Analyzer, opts v1.CreateOptions) (result *v1beta1.Analyzer, err error) {
|
||||
result = &v1beta1.Analyzer{}
|
||||
err = c.client.Post().
|
||||
Namespace(c.ns).
|
||||
Resource("analyzers").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(analyzer).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a analyzer and updates it. Returns the server's representation of the analyzer, and an error, if there is any.
|
||||
func (c *analyzers) Update(ctx context.Context, analyzer *v1beta1.Analyzer, opts v1.UpdateOptions) (result *v1beta1.Analyzer, err error) {
|
||||
result = &v1beta1.Analyzer{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("analyzers").
|
||||
Name(analyzer.Name).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(analyzer).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
func (c *analyzers) UpdateStatus(ctx context.Context, analyzer *v1beta1.Analyzer, opts v1.UpdateOptions) (result *v1beta1.Analyzer, err error) {
|
||||
result = &v1beta1.Analyzer{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("analyzers").
|
||||
Name(analyzer.Name).
|
||||
SubResource("status").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(analyzer).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the analyzer and deletes it. Returns an error if one occurs.
|
||||
func (c *analyzers) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("analyzers").
|
||||
Name(name).
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *analyzers) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
var timeout time.Duration
|
||||
if listOpts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("analyzers").
|
||||
VersionedParams(&listOpts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched analyzer.
|
||||
func (c *analyzers) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.Analyzer, err error) {
|
||||
result = &v1beta1.Analyzer{}
|
||||
err = c.client.Patch(pt).
|
||||
Namespace(c.ns).
|
||||
Resource("analyzers").
|
||||
Name(name).
|
||||
SubResource(subresources...).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(data).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
-194
@@ -1,194 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 Replicated, Inc..
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
v1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
|
||||
scheme "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/scheme"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
// CollectorsGetter has a method to return a CollectorInterface.
|
||||
// A group's client should implement this interface.
|
||||
type CollectorsGetter interface {
|
||||
Collectors(namespace string) CollectorInterface
|
||||
}
|
||||
|
||||
// CollectorInterface has methods to work with Collector resources.
|
||||
type CollectorInterface interface {
|
||||
Create(ctx context.Context, collector *v1beta1.Collector, opts v1.CreateOptions) (*v1beta1.Collector, error)
|
||||
Update(ctx context.Context, collector *v1beta1.Collector, opts v1.UpdateOptions) (*v1beta1.Collector, error)
|
||||
UpdateStatus(ctx context.Context, collector *v1beta1.Collector, opts v1.UpdateOptions) (*v1beta1.Collector, error)
|
||||
Delete(ctx context.Context, name string, opts v1.DeleteOptions) error
|
||||
DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error
|
||||
Get(ctx context.Context, name string, opts v1.GetOptions) (*v1beta1.Collector, error)
|
||||
List(ctx context.Context, opts v1.ListOptions) (*v1beta1.CollectorList, error)
|
||||
Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error)
|
||||
Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.Collector, err error)
|
||||
CollectorExpansion
|
||||
}
|
||||
|
||||
// collectors implements CollectorInterface
|
||||
type collectors struct {
|
||||
client rest.Interface
|
||||
ns string
|
||||
}
|
||||
|
||||
// newCollectors returns a Collectors
|
||||
func newCollectors(c *TroubleshootV1beta1Client, namespace string) *collectors {
|
||||
return &collectors{
|
||||
client: c.RESTClient(),
|
||||
ns: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
// Get takes name of the collector, and returns the corresponding collector object, and an error if there is any.
|
||||
func (c *collectors) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.Collector, err error) {
|
||||
result = &v1beta1.Collector{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("collectors").
|
||||
Name(name).
|
||||
VersionedParams(&options, scheme.ParameterCodec).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of Collectors that match those selectors.
|
||||
func (c *collectors) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.CollectorList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
result = &v1beta1.CollectorList{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("collectors").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested collectors.
|
||||
func (c *collectors) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
opts.Watch = true
|
||||
return c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("collectors").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Watch(ctx)
|
||||
}
|
||||
|
||||
// Create takes the representation of a collector and creates it. Returns the server's representation of the collector, and an error, if there is any.
|
||||
func (c *collectors) Create(ctx context.Context, collector *v1beta1.Collector, opts v1.CreateOptions) (result *v1beta1.Collector, err error) {
|
||||
result = &v1beta1.Collector{}
|
||||
err = c.client.Post().
|
||||
Namespace(c.ns).
|
||||
Resource("collectors").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(collector).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a collector and updates it. Returns the server's representation of the collector, and an error, if there is any.
|
||||
func (c *collectors) Update(ctx context.Context, collector *v1beta1.Collector, opts v1.UpdateOptions) (result *v1beta1.Collector, err error) {
|
||||
result = &v1beta1.Collector{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("collectors").
|
||||
Name(collector.Name).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(collector).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
func (c *collectors) UpdateStatus(ctx context.Context, collector *v1beta1.Collector, opts v1.UpdateOptions) (result *v1beta1.Collector, err error) {
|
||||
result = &v1beta1.Collector{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("collectors").
|
||||
Name(collector.Name).
|
||||
SubResource("status").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(collector).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the collector and deletes it. Returns an error if one occurs.
|
||||
func (c *collectors) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("collectors").
|
||||
Name(name).
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *collectors) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
var timeout time.Duration
|
||||
if listOpts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("collectors").
|
||||
VersionedParams(&listOpts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched collector.
|
||||
func (c *collectors) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.Collector, err error) {
|
||||
result = &v1beta1.Collector{}
|
||||
err = c.client.Patch(pt).
|
||||
Namespace(c.ns).
|
||||
Resource("collectors").
|
||||
Name(name).
|
||||
SubResource(subresources...).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(data).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 Replicated, Inc..
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
// This package has the automatically generated typed clients.
|
||||
package v1beta1
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 Replicated, Inc..
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
// Package fake has the automatically generated clients.
|
||||
package fake
|
||||
-141
@@ -1,141 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 Replicated, Inc..
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
v1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
labels "k8s.io/apimachinery/pkg/labels"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
testing "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
// FakeAnalyzers implements AnalyzerInterface
|
||||
type FakeAnalyzers struct {
|
||||
Fake *FakeTroubleshootV1beta1
|
||||
ns string
|
||||
}
|
||||
|
||||
var analyzersResource = schema.GroupVersionResource{Group: "troubleshoot.replicated.com", Version: "v1beta1", Resource: "analyzers"}
|
||||
|
||||
var analyzersKind = schema.GroupVersionKind{Group: "troubleshoot.replicated.com", Version: "v1beta1", Kind: "Analyzer"}
|
||||
|
||||
// Get takes name of the analyzer, and returns the corresponding analyzer object, and an error if there is any.
|
||||
func (c *FakeAnalyzers) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.Analyzer, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewGetAction(analyzersResource, c.ns, name), &v1beta1.Analyzer{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.Analyzer), err
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of Analyzers that match those selectors.
|
||||
func (c *FakeAnalyzers) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.AnalyzerList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewListAction(analyzersResource, analyzersKind, c.ns, opts), &v1beta1.AnalyzerList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label, _, _ := testing.ExtractFromListOptions(opts)
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &v1beta1.AnalyzerList{ListMeta: obj.(*v1beta1.AnalyzerList).ListMeta}
|
||||
for _, item := range obj.(*v1beta1.AnalyzerList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested analyzers.
|
||||
func (c *FakeAnalyzers) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewWatchAction(analyzersResource, c.ns, opts))
|
||||
|
||||
}
|
||||
|
||||
// Create takes the representation of a analyzer and creates it. Returns the server's representation of the analyzer, and an error, if there is any.
|
||||
func (c *FakeAnalyzers) Create(ctx context.Context, analyzer *v1beta1.Analyzer, opts v1.CreateOptions) (result *v1beta1.Analyzer, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewCreateAction(analyzersResource, c.ns, analyzer), &v1beta1.Analyzer{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.Analyzer), err
|
||||
}
|
||||
|
||||
// Update takes the representation of a analyzer and updates it. Returns the server's representation of the analyzer, and an error, if there is any.
|
||||
func (c *FakeAnalyzers) Update(ctx context.Context, analyzer *v1beta1.Analyzer, opts v1.UpdateOptions) (result *v1beta1.Analyzer, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateAction(analyzersResource, c.ns, analyzer), &v1beta1.Analyzer{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.Analyzer), err
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
func (c *FakeAnalyzers) UpdateStatus(ctx context.Context, analyzer *v1beta1.Analyzer, opts v1.UpdateOptions) (*v1beta1.Analyzer, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateSubresourceAction(analyzersResource, "status", c.ns, analyzer), &v1beta1.Analyzer{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.Analyzer), err
|
||||
}
|
||||
|
||||
// Delete takes name of the analyzer and deletes it. Returns an error if one occurs.
|
||||
func (c *FakeAnalyzers) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewDeleteAction(analyzersResource, c.ns, name), &v1beta1.Analyzer{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *FakeAnalyzers) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
action := testing.NewDeleteCollectionAction(analyzersResource, c.ns, listOpts)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &v1beta1.AnalyzerList{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched analyzer.
|
||||
func (c *FakeAnalyzers) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.Analyzer, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewPatchSubresourceAction(analyzersResource, c.ns, name, pt, data, subresources...), &v1beta1.Analyzer{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.Analyzer), err
|
||||
}
|
||||
-141
@@ -1,141 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 Replicated, Inc..
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
v1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
labels "k8s.io/apimachinery/pkg/labels"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
testing "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
// FakeCollectors implements CollectorInterface
|
||||
type FakeCollectors struct {
|
||||
Fake *FakeTroubleshootV1beta1
|
||||
ns string
|
||||
}
|
||||
|
||||
var collectorsResource = schema.GroupVersionResource{Group: "troubleshoot.replicated.com", Version: "v1beta1", Resource: "collectors"}
|
||||
|
||||
var collectorsKind = schema.GroupVersionKind{Group: "troubleshoot.replicated.com", Version: "v1beta1", Kind: "Collector"}
|
||||
|
||||
// Get takes name of the collector, and returns the corresponding collector object, and an error if there is any.
|
||||
func (c *FakeCollectors) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.Collector, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewGetAction(collectorsResource, c.ns, name), &v1beta1.Collector{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.Collector), err
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of Collectors that match those selectors.
|
||||
func (c *FakeCollectors) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.CollectorList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewListAction(collectorsResource, collectorsKind, c.ns, opts), &v1beta1.CollectorList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label, _, _ := testing.ExtractFromListOptions(opts)
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &v1beta1.CollectorList{ListMeta: obj.(*v1beta1.CollectorList).ListMeta}
|
||||
for _, item := range obj.(*v1beta1.CollectorList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested collectors.
|
||||
func (c *FakeCollectors) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewWatchAction(collectorsResource, c.ns, opts))
|
||||
|
||||
}
|
||||
|
||||
// Create takes the representation of a collector and creates it. Returns the server's representation of the collector, and an error, if there is any.
|
||||
func (c *FakeCollectors) Create(ctx context.Context, collector *v1beta1.Collector, opts v1.CreateOptions) (result *v1beta1.Collector, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewCreateAction(collectorsResource, c.ns, collector), &v1beta1.Collector{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.Collector), err
|
||||
}
|
||||
|
||||
// Update takes the representation of a collector and updates it. Returns the server's representation of the collector, and an error, if there is any.
|
||||
func (c *FakeCollectors) Update(ctx context.Context, collector *v1beta1.Collector, opts v1.UpdateOptions) (result *v1beta1.Collector, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateAction(collectorsResource, c.ns, collector), &v1beta1.Collector{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.Collector), err
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
func (c *FakeCollectors) UpdateStatus(ctx context.Context, collector *v1beta1.Collector, opts v1.UpdateOptions) (*v1beta1.Collector, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateSubresourceAction(collectorsResource, "status", c.ns, collector), &v1beta1.Collector{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.Collector), err
|
||||
}
|
||||
|
||||
// Delete takes name of the collector and deletes it. Returns an error if one occurs.
|
||||
func (c *FakeCollectors) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewDeleteAction(collectorsResource, c.ns, name), &v1beta1.Collector{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *FakeCollectors) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
action := testing.NewDeleteCollectionAction(collectorsResource, c.ns, listOpts)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &v1beta1.CollectorList{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched collector.
|
||||
func (c *FakeCollectors) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.Collector, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewPatchSubresourceAction(collectorsResource, c.ns, name, pt, data, subresources...), &v1beta1.Collector{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.Collector), err
|
||||
}
|
||||
-141
@@ -1,141 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 Replicated, Inc..
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
v1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
labels "k8s.io/apimachinery/pkg/labels"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
testing "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
// FakePreflights implements PreflightInterface
|
||||
type FakePreflights struct {
|
||||
Fake *FakeTroubleshootV1beta1
|
||||
ns string
|
||||
}
|
||||
|
||||
var preflightsResource = schema.GroupVersionResource{Group: "troubleshoot.replicated.com", Version: "v1beta1", Resource: "preflights"}
|
||||
|
||||
var preflightsKind = schema.GroupVersionKind{Group: "troubleshoot.replicated.com", Version: "v1beta1", Kind: "Preflight"}
|
||||
|
||||
// Get takes name of the preflight, and returns the corresponding preflight object, and an error if there is any.
|
||||
func (c *FakePreflights) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.Preflight, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewGetAction(preflightsResource, c.ns, name), &v1beta1.Preflight{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.Preflight), err
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of Preflights that match those selectors.
|
||||
func (c *FakePreflights) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.PreflightList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewListAction(preflightsResource, preflightsKind, c.ns, opts), &v1beta1.PreflightList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label, _, _ := testing.ExtractFromListOptions(opts)
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &v1beta1.PreflightList{ListMeta: obj.(*v1beta1.PreflightList).ListMeta}
|
||||
for _, item := range obj.(*v1beta1.PreflightList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested preflights.
|
||||
func (c *FakePreflights) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewWatchAction(preflightsResource, c.ns, opts))
|
||||
|
||||
}
|
||||
|
||||
// Create takes the representation of a preflight and creates it. Returns the server's representation of the preflight, and an error, if there is any.
|
||||
func (c *FakePreflights) Create(ctx context.Context, preflight *v1beta1.Preflight, opts v1.CreateOptions) (result *v1beta1.Preflight, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewCreateAction(preflightsResource, c.ns, preflight), &v1beta1.Preflight{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.Preflight), err
|
||||
}
|
||||
|
||||
// Update takes the representation of a preflight and updates it. Returns the server's representation of the preflight, and an error, if there is any.
|
||||
func (c *FakePreflights) Update(ctx context.Context, preflight *v1beta1.Preflight, opts v1.UpdateOptions) (result *v1beta1.Preflight, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateAction(preflightsResource, c.ns, preflight), &v1beta1.Preflight{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.Preflight), err
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
func (c *FakePreflights) UpdateStatus(ctx context.Context, preflight *v1beta1.Preflight, opts v1.UpdateOptions) (*v1beta1.Preflight, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateSubresourceAction(preflightsResource, "status", c.ns, preflight), &v1beta1.Preflight{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.Preflight), err
|
||||
}
|
||||
|
||||
// Delete takes name of the preflight and deletes it. Returns an error if one occurs.
|
||||
func (c *FakePreflights) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewDeleteAction(preflightsResource, c.ns, name), &v1beta1.Preflight{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *FakePreflights) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
action := testing.NewDeleteCollectionAction(preflightsResource, c.ns, listOpts)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &v1beta1.PreflightList{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched preflight.
|
||||
func (c *FakePreflights) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.Preflight, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewPatchSubresourceAction(preflightsResource, c.ns, name, pt, data, subresources...), &v1beta1.Preflight{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.Preflight), err
|
||||
}
|
||||
-141
@@ -1,141 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 Replicated, Inc..
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
v1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
labels "k8s.io/apimachinery/pkg/labels"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
testing "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
// FakeRedactors implements RedactorInterface
|
||||
type FakeRedactors struct {
|
||||
Fake *FakeTroubleshootV1beta1
|
||||
ns string
|
||||
}
|
||||
|
||||
var redactorsResource = schema.GroupVersionResource{Group: "troubleshoot.replicated.com", Version: "v1beta1", Resource: "redactors"}
|
||||
|
||||
var redactorsKind = schema.GroupVersionKind{Group: "troubleshoot.replicated.com", Version: "v1beta1", Kind: "Redactor"}
|
||||
|
||||
// Get takes name of the redactor, and returns the corresponding redactor object, and an error if there is any.
|
||||
func (c *FakeRedactors) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.Redactor, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewGetAction(redactorsResource, c.ns, name), &v1beta1.Redactor{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.Redactor), err
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of Redactors that match those selectors.
|
||||
func (c *FakeRedactors) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.RedactorList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewListAction(redactorsResource, redactorsKind, c.ns, opts), &v1beta1.RedactorList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label, _, _ := testing.ExtractFromListOptions(opts)
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &v1beta1.RedactorList{ListMeta: obj.(*v1beta1.RedactorList).ListMeta}
|
||||
for _, item := range obj.(*v1beta1.RedactorList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested redactors.
|
||||
func (c *FakeRedactors) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewWatchAction(redactorsResource, c.ns, opts))
|
||||
|
||||
}
|
||||
|
||||
// Create takes the representation of a redactor and creates it. Returns the server's representation of the redactor, and an error, if there is any.
|
||||
func (c *FakeRedactors) Create(ctx context.Context, redactor *v1beta1.Redactor, opts v1.CreateOptions) (result *v1beta1.Redactor, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewCreateAction(redactorsResource, c.ns, redactor), &v1beta1.Redactor{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.Redactor), err
|
||||
}
|
||||
|
||||
// Update takes the representation of a redactor and updates it. Returns the server's representation of the redactor, and an error, if there is any.
|
||||
func (c *FakeRedactors) Update(ctx context.Context, redactor *v1beta1.Redactor, opts v1.UpdateOptions) (result *v1beta1.Redactor, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateAction(redactorsResource, c.ns, redactor), &v1beta1.Redactor{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.Redactor), err
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
func (c *FakeRedactors) UpdateStatus(ctx context.Context, redactor *v1beta1.Redactor, opts v1.UpdateOptions) (*v1beta1.Redactor, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateSubresourceAction(redactorsResource, "status", c.ns, redactor), &v1beta1.Redactor{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.Redactor), err
|
||||
}
|
||||
|
||||
// Delete takes name of the redactor and deletes it. Returns an error if one occurs.
|
||||
func (c *FakeRedactors) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewDeleteAction(redactorsResource, c.ns, name), &v1beta1.Redactor{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *FakeRedactors) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
action := testing.NewDeleteCollectionAction(redactorsResource, c.ns, listOpts)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &v1beta1.RedactorList{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched redactor.
|
||||
func (c *FakeRedactors) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.Redactor, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewPatchSubresourceAction(redactorsResource, c.ns, name, pt, data, subresources...), &v1beta1.Redactor{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.Redactor), err
|
||||
}
|
||||
-141
@@ -1,141 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 Replicated, Inc..
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
v1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
labels "k8s.io/apimachinery/pkg/labels"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
testing "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
// FakeSupportBundles implements SupportBundleInterface
|
||||
type FakeSupportBundles struct {
|
||||
Fake *FakeTroubleshootV1beta1
|
||||
ns string
|
||||
}
|
||||
|
||||
var supportbundlesResource = schema.GroupVersionResource{Group: "troubleshoot.replicated.com", Version: "v1beta1", Resource: "supportbundles"}
|
||||
|
||||
var supportbundlesKind = schema.GroupVersionKind{Group: "troubleshoot.replicated.com", Version: "v1beta1", Kind: "SupportBundle"}
|
||||
|
||||
// Get takes name of the supportBundle, and returns the corresponding supportBundle object, and an error if there is any.
|
||||
func (c *FakeSupportBundles) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.SupportBundle, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewGetAction(supportbundlesResource, c.ns, name), &v1beta1.SupportBundle{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.SupportBundle), err
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of SupportBundles that match those selectors.
|
||||
func (c *FakeSupportBundles) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.SupportBundleList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewListAction(supportbundlesResource, supportbundlesKind, c.ns, opts), &v1beta1.SupportBundleList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label, _, _ := testing.ExtractFromListOptions(opts)
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &v1beta1.SupportBundleList{ListMeta: obj.(*v1beta1.SupportBundleList).ListMeta}
|
||||
for _, item := range obj.(*v1beta1.SupportBundleList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested supportBundles.
|
||||
func (c *FakeSupportBundles) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewWatchAction(supportbundlesResource, c.ns, opts))
|
||||
|
||||
}
|
||||
|
||||
// Create takes the representation of a supportBundle and creates it. Returns the server's representation of the supportBundle, and an error, if there is any.
|
||||
func (c *FakeSupportBundles) Create(ctx context.Context, supportBundle *v1beta1.SupportBundle, opts v1.CreateOptions) (result *v1beta1.SupportBundle, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewCreateAction(supportbundlesResource, c.ns, supportBundle), &v1beta1.SupportBundle{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.SupportBundle), err
|
||||
}
|
||||
|
||||
// Update takes the representation of a supportBundle and updates it. Returns the server's representation of the supportBundle, and an error, if there is any.
|
||||
func (c *FakeSupportBundles) Update(ctx context.Context, supportBundle *v1beta1.SupportBundle, opts v1.UpdateOptions) (result *v1beta1.SupportBundle, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateAction(supportbundlesResource, c.ns, supportBundle), &v1beta1.SupportBundle{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.SupportBundle), err
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
func (c *FakeSupportBundles) UpdateStatus(ctx context.Context, supportBundle *v1beta1.SupportBundle, opts v1.UpdateOptions) (*v1beta1.SupportBundle, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateSubresourceAction(supportbundlesResource, "status", c.ns, supportBundle), &v1beta1.SupportBundle{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.SupportBundle), err
|
||||
}
|
||||
|
||||
// Delete takes name of the supportBundle and deletes it. Returns an error if one occurs.
|
||||
func (c *FakeSupportBundles) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewDeleteAction(supportbundlesResource, c.ns, name), &v1beta1.SupportBundle{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *FakeSupportBundles) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
action := testing.NewDeleteCollectionAction(supportbundlesResource, c.ns, listOpts)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &v1beta1.SupportBundleList{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched supportBundle.
|
||||
func (c *FakeSupportBundles) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.SupportBundle, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewPatchSubresourceAction(supportbundlesResource, c.ns, name, pt, data, subresources...), &v1beta1.SupportBundle{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.SupportBundle), err
|
||||
}
|
||||
-55
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 Replicated, Inc..
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
v1beta1 "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1"
|
||||
rest "k8s.io/client-go/rest"
|
||||
testing "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
type FakeTroubleshootV1beta1 struct {
|
||||
*testing.Fake
|
||||
}
|
||||
|
||||
func (c *FakeTroubleshootV1beta1) Analyzers(namespace string) v1beta1.AnalyzerInterface {
|
||||
return &FakeAnalyzers{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeTroubleshootV1beta1) Collectors(namespace string) v1beta1.CollectorInterface {
|
||||
return &FakeCollectors{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeTroubleshootV1beta1) Preflights(namespace string) v1beta1.PreflightInterface {
|
||||
return &FakePreflights{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeTroubleshootV1beta1) Redactors(namespace string) v1beta1.RedactorInterface {
|
||||
return &FakeRedactors{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeTroubleshootV1beta1) SupportBundles(namespace string) v1beta1.SupportBundleInterface {
|
||||
return &FakeSupportBundles{c, namespace}
|
||||
}
|
||||
|
||||
// RESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *FakeTroubleshootV1beta1) RESTClient() rest.Interface {
|
||||
var ret *rest.RESTClient
|
||||
return ret
|
||||
}
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 Replicated, Inc..
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
type AnalyzerExpansion interface{}
|
||||
|
||||
type CollectorExpansion interface{}
|
||||
|
||||
type PreflightExpansion interface{}
|
||||
|
||||
type RedactorExpansion interface{}
|
||||
|
||||
type SupportBundleExpansion interface{}
|
||||
-194
@@ -1,194 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 Replicated, Inc..
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
v1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
|
||||
scheme "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/scheme"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
// PreflightsGetter has a method to return a PreflightInterface.
|
||||
// A group's client should implement this interface.
|
||||
type PreflightsGetter interface {
|
||||
Preflights(namespace string) PreflightInterface
|
||||
}
|
||||
|
||||
// PreflightInterface has methods to work with Preflight resources.
|
||||
type PreflightInterface interface {
|
||||
Create(ctx context.Context, preflight *v1beta1.Preflight, opts v1.CreateOptions) (*v1beta1.Preflight, error)
|
||||
Update(ctx context.Context, preflight *v1beta1.Preflight, opts v1.UpdateOptions) (*v1beta1.Preflight, error)
|
||||
UpdateStatus(ctx context.Context, preflight *v1beta1.Preflight, opts v1.UpdateOptions) (*v1beta1.Preflight, error)
|
||||
Delete(ctx context.Context, name string, opts v1.DeleteOptions) error
|
||||
DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error
|
||||
Get(ctx context.Context, name string, opts v1.GetOptions) (*v1beta1.Preflight, error)
|
||||
List(ctx context.Context, opts v1.ListOptions) (*v1beta1.PreflightList, error)
|
||||
Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error)
|
||||
Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.Preflight, err error)
|
||||
PreflightExpansion
|
||||
}
|
||||
|
||||
// preflights implements PreflightInterface
|
||||
type preflights struct {
|
||||
client rest.Interface
|
||||
ns string
|
||||
}
|
||||
|
||||
// newPreflights returns a Preflights
|
||||
func newPreflights(c *TroubleshootV1beta1Client, namespace string) *preflights {
|
||||
return &preflights{
|
||||
client: c.RESTClient(),
|
||||
ns: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
// Get takes name of the preflight, and returns the corresponding preflight object, and an error if there is any.
|
||||
func (c *preflights) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.Preflight, err error) {
|
||||
result = &v1beta1.Preflight{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("preflights").
|
||||
Name(name).
|
||||
VersionedParams(&options, scheme.ParameterCodec).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of Preflights that match those selectors.
|
||||
func (c *preflights) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.PreflightList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
result = &v1beta1.PreflightList{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("preflights").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested preflights.
|
||||
func (c *preflights) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
opts.Watch = true
|
||||
return c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("preflights").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Watch(ctx)
|
||||
}
|
||||
|
||||
// Create takes the representation of a preflight and creates it. Returns the server's representation of the preflight, and an error, if there is any.
|
||||
func (c *preflights) Create(ctx context.Context, preflight *v1beta1.Preflight, opts v1.CreateOptions) (result *v1beta1.Preflight, err error) {
|
||||
result = &v1beta1.Preflight{}
|
||||
err = c.client.Post().
|
||||
Namespace(c.ns).
|
||||
Resource("preflights").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(preflight).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a preflight and updates it. Returns the server's representation of the preflight, and an error, if there is any.
|
||||
func (c *preflights) Update(ctx context.Context, preflight *v1beta1.Preflight, opts v1.UpdateOptions) (result *v1beta1.Preflight, err error) {
|
||||
result = &v1beta1.Preflight{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("preflights").
|
||||
Name(preflight.Name).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(preflight).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
func (c *preflights) UpdateStatus(ctx context.Context, preflight *v1beta1.Preflight, opts v1.UpdateOptions) (result *v1beta1.Preflight, err error) {
|
||||
result = &v1beta1.Preflight{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("preflights").
|
||||
Name(preflight.Name).
|
||||
SubResource("status").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(preflight).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the preflight and deletes it. Returns an error if one occurs.
|
||||
func (c *preflights) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("preflights").
|
||||
Name(name).
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *preflights) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
var timeout time.Duration
|
||||
if listOpts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("preflights").
|
||||
VersionedParams(&listOpts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched preflight.
|
||||
func (c *preflights) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.Preflight, err error) {
|
||||
result = &v1beta1.Preflight{}
|
||||
err = c.client.Patch(pt).
|
||||
Namespace(c.ns).
|
||||
Resource("preflights").
|
||||
Name(name).
|
||||
SubResource(subresources...).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(data).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user