Compare commits

...

84 Commits

Author SHA1 Message Date
Alex Jones
391c3fa7a8 Merge pull request #160 from k8sgpt-ai/release-please--branches--main
chore(main): release 0.1.5
2023-03-31 15:08:22 +01:00
github-actions[bot]
8e99076497 chore(main): release 0.1.5 2023-03-31 14:04:36 +00:00
Alex Jones
c2b8732a5c Merge pull request #161 from matthisholleville/feature/add-and-remove-filters
feat: add & remove default filter(s) to analyze.
2023-03-31 15:04:01 +01:00
Matthis Holleville
3ed545f33f feat: rework filters
Signed-off-by: Matthis Holleville <matthish29@gmail.com>
2023-03-31 15:46:20 +02:00
Matthis Holleville
975813d328 feat: check if filters does not empty on add & remove
Signed-off-by: Matthis Holleville <matthish29@gmail.com>
2023-03-31 13:57:03 +02:00
Matthis Holleville
9aa0e8960e feat: update filters add & remove to be more consistent
Signed-off-by: Matthis Holleville <matthish29@gmail.com>
2023-03-31 13:30:59 +02:00
Matthis Holleville
0a124484a2 fix: spelling on dupplicateFilters
Signed-off-by: Matthis Holleville <matthish29@gmail.com>
2023-03-31 13:02:26 +02:00
Matthis Holleville
30faf84254 feat: remove filter prefix on subcommand
Signed-off-by: Matthis Holleville <matthish29@gmail.com>
2023-03-31 12:59:19 +02:00
Matthis Holleville
9ebb7de3c0 Merge branch 'main' into feature/add-and-remove-filters 2023-03-31 11:19:40 +02:00
Roberth Strand
9e9cd7083d Merge pull request #166 from matthisholleville/fix/kubecontext-has-no-effect
fix: kubecontext flag has no effect
2023-03-31 11:15:58 +02:00
Matthis Holleville
a8bf45134f fix: kubecontext flag has no effect
Signed-off-by: Matthis Holleville <matthish29@gmail.com>
2023-03-31 10:41:50 +02:00
Alex Jones
4d5449f97a Merge pull request #165 from k8sgpt-ai/chore/filterlist-file
chore: renamed filter list file
2023-03-31 09:07:39 +01:00
AlexsJones
25f8dc390c chore: renamed filter list file
Signed-off-by: AlexsJones <alexsimonjones@gmail.com>
2023-03-31 09:07:08 +01:00
Matthis Holleville
32ddf6691c feat: add & remove default filter(s) to analyze.
Signed-off-by: Matthis Holleville <matthish29@gmail.com>
2023-03-30 23:18:43 +02:00
HOLLEVILLE Matthis
6e17c9e285 feat: add filter command add "list" subcommand (#159)
* feat: add filter command add "list" subcommand to display available filters

Signed-off-by: Matthis Holleville <matthish29@gmail.com>

* feat: create specific file to filterList

Signed-off-by: Matthis Holleville <matthish29@gmail.com>

* feat: rename ListAnalyzers to ListFilters

Signed-off-by: Matthis Holleville <matthish29@gmail.com>

---------

Signed-off-by: Matthis Holleville <matthish29@gmail.com>
2023-03-30 20:58:41 +02:00
Alex Jones
9f0cb6240e Merge pull request #152 from k8sgpt-ai/release-please--branches--main
chore(main): release 0.1.4
2023-03-30 13:42:14 +01:00
github-actions[bot]
26db0f6941 chore(main): release 0.1.4 2023-03-30 12:29:37 +00:00
Alex Jones
2acab541bc Merge pull request #155 from k8sgpt-ai/fix/kubectx
fix: now supports different kubeconfig and kubectx
2023-03-30 13:29:05 +01:00
Thomas Schuetz
53a19bb04d Merge branch 'main' into fix/kubectx 2023-03-30 14:27:56 +02:00
Alex Jones
c8f3c946b0 fix: now supports different kubeconfig and kubectx
Signed-off-by: Alex Jones <alexsimonjones@gmail.com>
2023-03-30 12:49:02 +01:00
HOLLEVILLE Matthis
b061566404 feat: add Ingress class validation (#154)
Signed-off-by: Matthis Holleville <matthish29@gmail.com>
2023-03-30 13:48:53 +02:00
Alexandre Steppé
be061da5b6 feat: output selected backend (#153)
Signed-off-by: Alexandre Steppé <alexandre.steppe@gmail.com>
2023-03-30 13:37:10 +02:00
Roberth Strand
5f548421c7 Merge pull request #151 from k8sgpt-ai/feat/rs-cleanup
refactor: removed sample flag
2023-03-30 12:04:40 +02:00
Roberth Strand
0afd52844b refactor: removed sample flag
Commented out the sample flag that the framework comes with, as it was not in use. Choose to comment it out for now for easy reference, just in case we want to implement that type of toggle flags.

Signed-off-by: Roberth Strand <me@robstr.dev>
2023-03-30 11:48:43 +02:00
Alex Jones
f95c1e1d8c Merge pull request #130 from k8sgpt-ai/release-please--branches--main
chore(main): release 0.1.3
2023-03-30 09:00:17 +01:00
github-actions[bot]
3fc0d45823 chore(main): release 0.1.3 2023-03-30 07:51:31 +00:00
Alex Jones
cf633b606d Merge pull request #144 from matthisholleville/fix/ingress-object-meta-value
fix: ingress object meta value
2023-03-30 08:51:03 +01:00
Alex Jones
ab63bd0dd1 Merge branch 'main' into fix/ingress-object-meta-value 2023-03-30 08:49:48 +01:00
Alex Jones
3e05eb2af2 Merge pull request #149 from k8sgpt-ai/feat/analysis-speed
feat: analysis speed
2023-03-30 08:44:03 +01:00
Alex Jones
548039ebe6 feat: improvement to analysis speed
Signed-off-by: Alex Jones <alexsimonjones@gmail.com>
2023-03-30 08:19:35 +01:00
Alex Jones
0d5b8ad027 Merge branch 'main' of github.com:k8sgpt-ai/k8sgpt into main 2023-03-30 07:52:24 +01:00
Thomas Schuetz
0f910e497a Merge branch 'main' into fix/ingress-object-meta-value 2023-03-30 08:38:45 +02:00
Alex Jones
172c2df6c5 fix: bugfix for output (#148) 2023-03-30 08:38:11 +02:00
Alex Jones
2eab0c544f feat: bugfix for output
Signed-off-by: Alex Jones <alexsimonjones@gmail.com>
2023-03-30 07:28:42 +01:00
Chadi Laoulaou
f4765bed1b fix: typo in description of the filter flag in analyze command (#147)
Signed-off-by: Chadi Laoulaou <chadilaoulaou@gmail.com>
2023-03-30 05:38:47 +02:00
Matthis Holleville
14ba8d5550 fix: add Ingress in GetParent switch case
Signed-off-by: Matthis Holleville <matthish29@gmail.com>
2023-03-30 01:35:09 +02:00
Aris Boutselis
bf49a51c62 fix: Change ObjectMeta value in Ingress analyser.
Signed-off-by: Aris Boutselis <aris.boutselis@senseon.io>
2023-03-30 00:10:19 +01:00
HOLLEVILLE Matthis
86c7e81e18 feat: add secret validation to ingress analyzer (#141)
This commit adds a check to the ingress analyzer that verifies whether the secret declared in the ingress exists on the cluster. This helps to ensure that only valid secrets are used in the ingress configuration.

Signed-off-by: Matthis Holleville <matthish29@gmail.com>
2023-03-29 20:36:50 +00:00
Mike Levan
cdc7bb1272 readme update to specifiy WSL and Linux (#142)
Co-authored-by: michael levan <michael.levan@orbica.world>
2023-03-29 21:42:56 +02:00
HOLLEVILLE Matthis
fe683b71b8 feat: init ingress analyzer (#138)
Signed-off-by: Matthis Holleville <matthish29@gmail.com>
2023-03-29 18:27:05 +02:00
Sudipto Baral
cad2b38d03 docs: add new slack link (#134) (#135)
Signed-off-by: Sudipto Baral <sudiptobaral.me@gmail.com>
2023-03-29 06:51:58 +02:00
renovate[bot]
01b2826475 chore(deps): update google-github-actions/release-please-action digest to ee9822e (#132)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-28 22:59:29 +02:00
Alex Jones
4f24368758 Merge pull request #131 from k8sgpt-ai/feat/security-policy
feat: security.md
2023-03-28 21:21:05 +01:00
Alex Jones
27b8916f29 feat: create-security.md 2023-03-28 20:20:08 +00:00
Alex Jones
fe73633273 feat: CODE_OF_CONDUCT.md (#129) 2023-03-28 21:33:50 +02:00
Alex Jones
a9d7bd42c2 Merge pull request #120 from k8sgpt-ai/release-please--branches--main
chore(main): release 0.1.2
2023-03-28 20:26:23 +01:00
github-actions[bot]
2d481b8563 chore(main): release 0.1.2 2023-03-28 19:11:11 +00:00
Alex Jones
b78ab3d9b5 feat: added namespace filter (#127)
* feat: added namespace filter

Signed-off-by: AlexsJones <alexsimonjones@gmail.com>

* chore: Moved the explain bool out

Signed-off-by: AlexsJones <alexsimonjones@gmail.com>

---------

Signed-off-by: AlexsJones <alexsimonjones@gmail.com>
2023-03-28 21:10:42 +02:00
Thomas Schuetz
c8b92aaa0e fix: readme code blocks (#126)
Signed-off-by: Thomas Schuetz <thomas.schuetz@t-sc.eu>
2023-03-28 20:34:22 +02:00
Thomas Schuetz
65a568e937 feat: prefix templates (#125)
Signed-off-by: Thomas Schuetz <thomas.schuetz@t-sc.eu>
2023-03-28 20:30:59 +02:00
Thomas Schuetz
cb4932c39d docs: rename ISSUE_TEMPLATE (#124)
Signed-off-by: Thomas Schuetz <thomas.schuetz@t-sc.eu>
2023-03-28 20:27:42 +02:00
Alex Jones
323a8b23ec Merge pull request #122 from k8sgpt-ai/doc/issue_templates
docs: add new issue templates
2023-03-28 19:22:19 +01:00
Alex Jones
be5fb62bb7 Merge branch 'main' into doc/issue_templates 2023-03-28 19:22:12 +01:00
Alex Jones
e912a8ded0 Merge pull request #123 from k8sgpt-ai/doc/fix_readme
docs: add wsl gcc instructions
2023-03-28 19:21:59 +01:00
Thomas Schuetz
a46416dce0 docs: fix indentations
Signed-off-by: Thomas Schuetz <thomas.schuetz@t-sc.eu>
2023-03-28 19:41:50 +02:00
Thomas Schuetz
4d5566b4df docs: add WSL gcc instructions
Signed-off-by: Thomas Schuetz <thomas.schuetz@t-sc.eu>
2023-03-28 19:40:59 +02:00
Thomas Schuetz
dbd305f901 docs: add new issue templates
Signed-off-by: Thomas Schuetz <thomas.schuetz@t-sc.eu>
2023-03-28 19:22:54 +02:00
Sudipto Baral
11c227b82e chore: added default issue template (#96) (#121)
* chore: added default issue template (#96)

Signed-off-by: Sudipto Baral <sudiptobaral.me@gmail.com>

* chore: added addtional instruction through comment (#96)

Signed-off-by: Sudipto Baral <sudiptobaral.me@gmail.com>

---------

Signed-off-by: Sudipto Baral <sudiptobaral.me@gmail.com>
2023-03-28 18:55:19 +02:00
Alex Jones
05abe975dd fix: update README.md (#119) 2023-03-28 15:50:02 +02:00
Sai Kumar Peddireddy
3bfb278f81 docs: added Windows and Linux instalation steps in README (#116) 2023-03-28 15:45:48 +02:00
Alex Jones
b4865ff233 Merge pull request #106 from k8sgpt-ai/release-please--branches--main
chore(main): release 0.1.1
2023-03-28 14:05:31 +01:00
github-actions[bot]
95dfc62c4d chore(main): release 0.1.1 2023-03-28 13:02:54 +00:00
Alex Jones
b3efdf8525 Merge pull request #118 from k8sgpt-ai/feat/exhaustion
fix: short term solution for exhaustion
2023-03-28 14:02:21 +01:00
AlexsJones
5890e3a79c fix: short term solution for exhaustion
Signed-off-by: AlexsJones <alexsimonjones@gmail.com>
2023-03-28 14:00:50 +01:00
Alex Jones
d0e4684e82 Merge pull request #113 from k8sgpt-ai/fix/service-failure
fix: this stops service exiting the program
2023-03-28 13:02:00 +01:00
AlexsJones
6f90386fc9 feat: this stops service exiting the program
Signed-off-by: AlexsJones <alexsimonjones@gmail.com>
2023-03-28 12:56:28 +01:00
Alex Jones
2f699a9929 Merge pull request #111 from k8sgpt-ai/chore/readme-patch
chore: update README.md
2023-03-28 12:26:14 +01:00
Alex Jones
93b947f261 chore: update README.md 2023-03-28 12:22:39 +01:00
Alex Jones
54143ea0ee Merge pull request #109 from k8sgpt-ai/chore/AlexsJones-patch-1-1
chore: update root.go path
2023-03-28 12:19:40 +01:00
Alex Jones
2cb1c9c150 chore: update root.go path 2023-03-28 12:18:48 +01:00
Alex Jones
02f5f921e2 Merge pull request #104 from k8sgpt-ai/chore/readme-update
feat: updated readme
2023-03-28 12:05:05 +01:00
Alex Jones
e0141d1cf5 feat: updated readme
Signed-off-by: Alex Jones <alexsimonjones@gmail.com>
2023-03-28 11:51:50 +01:00
Alex Jones
d48ff1a942 Merge pull request #98 from k8sgpt-ai/release-please--branches--main
chore(main): release 0.1.0
2023-03-28 11:05:13 +01:00
github-actions[bot]
14f076a095 chore(main): release 0.1.0 2023-03-28 09:59:57 +00:00
Thomas Schuetz
829ff566c0 chore: add codeowners file (#102)
Signed-off-by: Thomas Schuetz <thomas.schuetz@t-sc.eu>
2023-03-28 11:59:32 +02:00
Alex Jones
0ecf248c3f Merge pull request #100 from k8sgpt-ai/chore/codeowners
chore: add CODEOWNERS
2023-03-28 10:59:00 +01:00
Thomas Schuetz
c5c6162df1 chore: add CODEOWNERS
Signed-off-by: Thomas Schuetz <thomas.schuetz@t-sc.eu>
2023-03-28 11:52:46 +02:00
Alex Jones
a270f7c89f feat: enables overwriting of cache (#95) 2023-03-28 11:43:12 +02:00
Thomas Schuetz
ff0b67b5a9 Merge branch 'main' of github.com:k8sgpt-ai/k8sgpt 2023-03-28 11:41:46 +02:00
Thomas Schuetz
f9c7daf3dc chore: release 0.1.0
Release-As: 0.1.0
Signed-off-by: Thomas Schuetz <thomas.schuetz@t-sc.eu>
2023-03-28 11:40:27 +02:00
Roberth Strand
a49cec98c0 Merge pull request #97 from k8sgpt-ai/feat/93-british-and-american-english
feat: added british alias
2023-03-28 11:18:21 +02:00
Roberth Strand
39c0444fac feat: added british alias
Added an alias for analyze with the British English variant analyse.

Closes #93

Signed-off-by: Roberth Strand <me@robstr.dev>
2023-03-28 11:07:45 +02:00
github-actions[bot]
0a0c88719e chore(main): release 0.0.9 (#91)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-03-28 07:22:32 +02:00
Thomas Schuetz
202e8e2977 chore: small update
Signed-off-by: Thomas Schuetz <thomas.schuetz@t-sc.eu>
2023-03-28 07:21:07 +02:00
25 changed files with 946 additions and 101 deletions

12
.github/CODEOWNERS vendored Normal file
View File

@@ -0,0 +1,12 @@
# CODEOWNERS file indicates code owners for certain files
#
# Code owners will automatically be added as a reviewer for PRs that touch
# the owned files.
#
# Default owners for everything in the repo
#
# Unless a later match takes precedence, these owners will be requested for
# review when someone opens a pull request.
* @k8sgpt-ai/maintainers

View File

@@ -0,0 +1,35 @@
---
name: Feature Request
about: Suggest an idea for this project
title: 'feature: '
labels: 'type:question'
assignees: '@k8sgpt-ai/maintainers'
---
<!--
Thank you for initiating this feature request 🤗
To ensure conciseness, kindly try to adhere to the following format.
-->
Checklist:
* [ ] I've searched for similar issues and couldn't find anything matching
* [ ] I've discussed this feature in the #k8sgpt slack channel
## Is this feature request related to a problem?
* [ ] Yes
* [ ] No
<!-- If yes, please provide a clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->
## Describe the solution you'd like
<!-- A clear and concise description of what you want to happen. -->
## Benefits for the project and its users
<!-- Describe the benefits this feature will bring to the project and its users. -->
## Potential drawbacks
<!-- Describe any potential drawbacks this feature might bring to the project and its users. -->
## Additional context
<!-- Add any other context about your feature request here. If applicable, add drawings to help explain. -->

50
.github/ISSUE_TEMPLATE/question.md vendored Normal file
View File

@@ -0,0 +1,50 @@
---
name: Question / Bug Report
about: Create a report to help us improve
title: 'question: '
labels: 'type:question'
assignees: ''
---
<!--
Thank you for initiating this issue request 🤗
To ensure conciseness, kindly try to adhere to the following format.
-->
Checklist:
* [ ] I've searched for similar issues and couldn't find anything matching
* [ ] I've included steps to reproduce the bug.
* [ ] I've included the version of Kubernetes and k8sgpt.
### Subject of the issue
<!-- Describe your issue here. -->
### Your environment
<!-- Describe your environment here. -->
* Version of Kubernetes
<!-- kubectl version -->
* Host OS and its version / If windows, is it WSL?
* Version of k8sgpt
<!-- k8sgpt version -->
### Steps to reproduce
<!-- Tell us how to reproduce this issue. -->
* Step 1
* Step 2
### Expected behaviour
<!-- Tell us what should happen -->
### Actual behaviour
<!-- Tell us what happens instead -->
### Additional context / screenshots
<!-- Add any other context about the problem here. If applicable, add screenshots to help explain. -->

View File

@@ -25,7 +25,7 @@ jobs:
- name: Checkout
uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 # v3
- uses: google-github-actions/release-please-action@e0b9d1885d92e9a93d5ce8656de60e3b806e542c # v3
- uses: google-github-actions/release-please-action@ee9822ec2c397e8a364d634464339ac43a06e042 # v3
id: release
with:
command: manifest

View File

@@ -1 +1 @@
{".":"0.0.8"}
{".":"0.1.5"}

View File

@@ -1,5 +1,145 @@
# Changelog
## [0.1.5](https://github.com/k8sgpt-ai/k8sgpt/compare/v0.1.4...v0.1.5) (2023-03-31)
### Features
* add & remove default filter(s) to analyze. ([32ddf66](https://github.com/k8sgpt-ai/k8sgpt/commit/32ddf6691ce083fd4283a1d5ac4b9f02e90df867))
* add filter command add "list" subcommand ([#159](https://github.com/k8sgpt-ai/k8sgpt/issues/159)) ([6e17c9e](https://github.com/k8sgpt-ai/k8sgpt/commit/6e17c9e285e3871bb8f694b734a8cd6fd02e60f0))
* check if filters does not empty on add & remove ([975813d](https://github.com/k8sgpt-ai/k8sgpt/commit/975813d3284719c877630ad20f90c6fe163283da))
* remove filter prefix on subcommand ([30faf84](https://github.com/k8sgpt-ai/k8sgpt/commit/30faf842541c0be6b6483f71f6cf04d5cafecef5))
* rework filters ([3ed545f](https://github.com/k8sgpt-ai/k8sgpt/commit/3ed545f33fb3ecb3827c03e8c89027c61386c44f))
* update filters add & remove to be more consistent ([9aa0e89](https://github.com/k8sgpt-ai/k8sgpt/commit/9aa0e8960ee340208b4749954c99867842ba58b9))
### Bug Fixes
* kubecontext flag has no effect ([a8bf451](https://github.com/k8sgpt-ai/k8sgpt/commit/a8bf45134ff3a72dc3e531d720f119790faff9d4))
* spelling on dupplicateFilters ([0a12448](https://github.com/k8sgpt-ai/k8sgpt/commit/0a124484a23789376258413e73628c7b1d7abded))
### Other
* renamed filter list file ([25f8dc3](https://github.com/k8sgpt-ai/k8sgpt/commit/25f8dc390cccd66965993f464351e671af11f8ac))
## [0.1.4](https://github.com/k8sgpt-ai/k8sgpt/compare/v0.1.3...v0.1.4) (2023-03-30)
### Features
* add Ingress class validation ([#154](https://github.com/k8sgpt-ai/k8sgpt/issues/154)) ([b061566](https://github.com/k8sgpt-ai/k8sgpt/commit/b061566404ef80288ca29add2d401574109d44c0))
* output selected backend ([#153](https://github.com/k8sgpt-ai/k8sgpt/issues/153)) ([be061da](https://github.com/k8sgpt-ai/k8sgpt/commit/be061da5b65045938acd70ad2eb2d21b87d2d6bf))
### Bug Fixes
* now supports different kubeconfig and kubectx ([c8f3c94](https://github.com/k8sgpt-ai/k8sgpt/commit/c8f3c946b00c00cd185961a4fa777806da94014e))
### Refactoring
* removed sample flag ([0afd528](https://github.com/k8sgpt-ai/k8sgpt/commit/0afd52844b96579391f77698bf0555145b6d2be8))
## [0.1.3](https://github.com/k8sgpt-ai/k8sgpt/compare/v0.1.2...v0.1.3) (2023-03-30)
### Features
* add secret validation to ingress analyzer ([#141](https://github.com/k8sgpt-ai/k8sgpt/issues/141)) ([86c7e81](https://github.com/k8sgpt-ai/k8sgpt/commit/86c7e81e18db02ebcbfe35d470682c982871375f))
* bugfix for output ([2eab0c5](https://github.com/k8sgpt-ai/k8sgpt/commit/2eab0c544fbb6026f6aea79b08d8f29c061acf2e))
* CODE_OF_CONDUCT.md ([#129](https://github.com/k8sgpt-ai/k8sgpt/issues/129)) ([fe73633](https://github.com/k8sgpt-ai/k8sgpt/commit/fe73633273c5c1f4188bca48471283535967d5aa))
* create-security.md ([27b8916](https://github.com/k8sgpt-ai/k8sgpt/commit/27b8916f297570907437686c6d958636fb249d50))
* improvement to analysis speed ([548039e](https://github.com/k8sgpt-ai/k8sgpt/commit/548039ebe62bb609c1aa288e5e49845850fd2dd8))
* init ingress analyzer ([#138](https://github.com/k8sgpt-ai/k8sgpt/issues/138)) ([fe683b7](https://github.com/k8sgpt-ai/k8sgpt/commit/fe683b71b84fe82459b0ffe366b4dcfa1c978cfe))
### Bug Fixes
* add Ingress in GetParent switch case ([14ba8d5](https://github.com/k8sgpt-ai/k8sgpt/commit/14ba8d555005f31fc2201cb8b61653093c19b8a7))
* bugfix for output ([#148](https://github.com/k8sgpt-ai/k8sgpt/issues/148)) ([172c2df](https://github.com/k8sgpt-ai/k8sgpt/commit/172c2df6c55f5fddbfec7f8526be5f2323d1b900))
* Change ObjectMeta value in Ingress analyser. ([bf49a51](https://github.com/k8sgpt-ai/k8sgpt/commit/bf49a51c62af450cff51a590547ef30989bd2e93))
* typo in description of the filter flag in analyze command ([#147](https://github.com/k8sgpt-ai/k8sgpt/issues/147)) ([f4765be](https://github.com/k8sgpt-ai/k8sgpt/commit/f4765bed1b1ad121a81b35878fdb866354b5e34a))
### Other
* **deps:** update google-github-actions/release-please-action digest to ee9822e ([#132](https://github.com/k8sgpt-ai/k8sgpt/issues/132)) ([01b2826](https://github.com/k8sgpt-ai/k8sgpt/commit/01b282647512a4eaebd42ab5847b5534de148d14))
### Docs
* add new slack link ([#134](https://github.com/k8sgpt-ai/k8sgpt/issues/134)) ([#135](https://github.com/k8sgpt-ai/k8sgpt/issues/135)) ([cad2b38](https://github.com/k8sgpt-ai/k8sgpt/commit/cad2b38d037658495024ec0166ebd3e936f65c2e))
## [0.1.2](https://github.com/k8sgpt-ai/k8sgpt/compare/v0.1.1...v0.1.2) (2023-03-28)
### Features
* added namespace filter ([#127](https://github.com/k8sgpt-ai/k8sgpt/issues/127)) ([b78ab3d](https://github.com/k8sgpt-ai/k8sgpt/commit/b78ab3d9b503a256bf6ccf18276e20140ae17d1c))
* prefix templates ([#125](https://github.com/k8sgpt-ai/k8sgpt/issues/125)) ([65a568e](https://github.com/k8sgpt-ai/k8sgpt/commit/65a568e937a8fdacc179f5e8b1a021a0178c04f0))
### Bug Fixes
* readme code blocks ([#126](https://github.com/k8sgpt-ai/k8sgpt/issues/126)) ([c8b92aa](https://github.com/k8sgpt-ai/k8sgpt/commit/c8b92aaa0e2795aa8d65f84277c8adfe0f1d14e3))
* update README.md ([#119](https://github.com/k8sgpt-ai/k8sgpt/issues/119)) ([05abe97](https://github.com/k8sgpt-ai/k8sgpt/commit/05abe975dd859cd85096a1a7182f17b0437ad20f))
### Other
* added default issue template ([#96](https://github.com/k8sgpt-ai/k8sgpt/issues/96)) ([#121](https://github.com/k8sgpt-ai/k8sgpt/issues/121)) ([11c227b](https://github.com/k8sgpt-ai/k8sgpt/commit/11c227b82e16dac8b46cbd03bb04d9cc1c2b5ac3))
### Docs
* add new issue templates ([dbd305f](https://github.com/k8sgpt-ai/k8sgpt/commit/dbd305f901cca09b7148254c3aa7a7435504d6cc))
* add WSL gcc instructions ([4d5566b](https://github.com/k8sgpt-ai/k8sgpt/commit/4d5566b4df7aedf43edbeeb03130f0ba77dbed1a))
* added Windows and Linux instalation steps in README ([#116](https://github.com/k8sgpt-ai/k8sgpt/issues/116)) ([3bfb278](https://github.com/k8sgpt-ai/k8sgpt/commit/3bfb278f81a9c550ee37a88c0cb0377331802542))
* fix indentations ([a46416d](https://github.com/k8sgpt-ai/k8sgpt/commit/a46416dce0f5cee2d42b27525023b04af1a8e3c0))
* rename ISSUE_TEMPLATE ([#124](https://github.com/k8sgpt-ai/k8sgpt/issues/124)) ([cb4932c](https://github.com/k8sgpt-ai/k8sgpt/commit/cb4932c39df4903a4b48ae5f0428860027f76fd2))
## [0.1.1](https://github.com/k8sgpt-ai/k8sgpt/compare/v0.1.0...v0.1.1) (2023-03-28)
### Features
* this stops service exiting the program ([6f90386](https://github.com/k8sgpt-ai/k8sgpt/commit/6f90386fc93b2e39e59832468922e8ba7210b8e5))
* updated readme ([e0141d1](https://github.com/k8sgpt-ai/k8sgpt/commit/e0141d1cf54b5b37b25a5caeb9d5c940b9410ea7))
### Bug Fixes
* short term solution for exhaustion ([5890e3a](https://github.com/k8sgpt-ai/k8sgpt/commit/5890e3a79c80a2973af2feb7d50e7f9c57c563c2))
### Other
* update README.md ([93b947f](https://github.com/k8sgpt-ai/k8sgpt/commit/93b947f261e401c10dde6dc1854e6e22187437d6))
* update root.go path ([2cb1c9c](https://github.com/k8sgpt-ai/k8sgpt/commit/2cb1c9c150d052bb3942d9f62ded9d54b0e1873e))
## [0.1.0](https://github.com/k8sgpt-ai/k8sgpt/compare/v0.0.9...v0.1.0) (2023-03-28)
### Features
* added british alias ([39c0444](https://github.com/k8sgpt-ai/k8sgpt/commit/39c0444fac9b46d0faa347b45df779b97019e5b6)), closes [#93](https://github.com/k8sgpt-ai/k8sgpt/issues/93)
* enables overwriting of cache ([#95](https://github.com/k8sgpt-ai/k8sgpt/issues/95)) ([a270f7c](https://github.com/k8sgpt-ai/k8sgpt/commit/a270f7c89fb8bec35984715c5e4d160a2307e678))
### Other
* add CODEOWNERS ([c5c6162](https://github.com/k8sgpt-ai/k8sgpt/commit/c5c6162df1f3701659e47bce6e9fc6e3c569e539))
* add codeowners file ([#102](https://github.com/k8sgpt-ai/k8sgpt/issues/102)) ([829ff56](https://github.com/k8sgpt-ai/k8sgpt/commit/829ff566c0a964250d3d8d45306d410e1b9d9d35))
* release 0.1.0 ([f9c7daf](https://github.com/k8sgpt-ai/k8sgpt/commit/f9c7daf3dcd06dcd9cea5603108b8a42ee273348))
## [0.0.9](https://github.com/k8sgpt-ai/k8sgpt/compare/v0.0.8...v0.0.9) (2023-03-28)
### Other
* small update ([202e8e2](https://github.com/k8sgpt-ai/k8sgpt/commit/202e8e2977422b2b4506a80dc9b76a392c5457eb))
## [0.0.8](https://github.com/k8sgpt-ai/k8sgpt/compare/v0.0.7...v0.0.8) (2023-03-27)

128
CODE_OF_CONDUCT.md Normal file
View File

@@ -0,0 +1,128 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
contact@k8sgpt.ai.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.

View File

@@ -7,16 +7,47 @@
It has SRE experience codified into it's analyzers and helps to pull out the most relevent information to enrich it with AI.
## Quick Start
## Installation
### Linux/Mac via brew
```
brew tap k8sgpt-ai/k8sgpt
brew install k8sgpt
```
<details>
<summary>Failing Installation on WSL or Linux (missing gcc)</summary>
When installing Homebrew on WSL or Linux, you may encounter the following error:
```
==> Installing k8sgpt from k8sgpt-ai/k8sgpt Error: The following formula cannot be installed from bottle and must be
built from source. k8sgpt Install Clang or run brew install gcc.
```
If you install gcc as suggested, the problem will persist. Therefore, you need to install the build-essential package.
```
sudo apt-get update
sudo apt-get install build-essential
```
</details>
### Windows
* Download the latest Windows binaries of **k8sgpt** from the [Release](https://github.com/k8sgpt-ai/k8sgpt/releases)
tab based on your system architecture.
* Extract the downloaded package to your desired location. Configure the system *path* variable with the binary location
### Verify installation
* Run `k8sgpt version`
## Quick Start
* Currently the default AI provider is OpenAI, you will need to generate an API key from [OpenAI](https://openai.com)
* You can do this by running `k8sgpt generate` to open a browser link to generate it
* You can do this by running `k8sgpt generate` to open a browser link to generate it
* Run `k8sgpt auth` to set it in k8sgpt.
* Run `k8sgpt filters` to manage the active filters used by the analyzer. By default, all filters are executed during analysis.
* Run `k8sgpt analyze` to run a scan.
* And use `k8sgpt analyze --explain` to get a more detailed explanation of the issues.
@@ -24,7 +55,8 @@ brew install k8sgpt
## Analyzers
K8sGPT uses analyzers to triage and diagnose issues in your cluster. It has a set of analyzers that are built in, but you will be able to write your own analyzers.
K8sGPT uses analyzers to triage and diagnose issues in your cluster. It has a set of analyzers that are built in, but
you will be able to write your own analyzers.
### Built in analyzers
@@ -33,6 +65,7 @@ K8sGPT uses analyzers to triage and diagnose issues in your cluster. It has a se
- [x] rsAnalyzer
- [x] serviceAnalyzer
- [x] eventAnalyzer
- [x] ingressAnalyzer
## Usage
@@ -44,6 +77,7 @@ Available Commands:
analyze This command will find problems within your Kubernetes cluster
auth Authenticate with your chosen backend
completion Generate the autocompletion script for the specified shell
filters Manage filters for analyzing Kubernetes resources
generate Generate Key for your chosen backend (opens browser)
help Help about any command
version Print the version number of k8sgpt
@@ -58,6 +92,36 @@ Flags:
Use "k8sgpt [command] --help" for more information about a command.
```
_Manage filters_
_List filters_
```
k8sgpt filters list
```
_Add default filters_
```
k8sgpt filters add [filter(s)]
```
### Examples :
- Simple filter : `k8sgpt filters add Service`
- Multiple filters : `k8sgpt filters add Ingress,Pod`
_Add default filters_
```
k8sgpt filters remove [filter(s)]
```
### Examples :
- Simple filter : `k8sgpt filters remove Service`
- Multiple filters : `k8sgpt filters remove Ingress,Pod`
_Run a scan with the default analyzers_
```
@@ -69,13 +133,18 @@ k8sgpt analyze --explain
_Filter on resource_
```
k8sgpt analyze --explain --resource=Service
k8sgpt analyze --explain --filter=Service
```
_Filter by namespace_
```
k8sgpt analyze --explain --filter=Pod --namespace=default
```
_Output to JSON_
```
k8sgpt analyze --explain --resource=Service --output=json
k8sgpt analyze --explain --filter=Service --output=json
```
## Upcoming major milestones
@@ -84,19 +153,22 @@ k8sgpt analyze --explain --resource=Service --output=json
- [ ] Custom AI/ML model backend support
- [ ] Custom analyzers
### What about kubectl-ai?
## What about kubectl-ai?
The the kubectl-ai [project](https://github.com/sozercan/kubectl-ai) uses AI to create manifests and apply them to the cluster. It is not what we are trying to do here, it is focusing on writing YAML manifests.
The kubectl-ai [project](https://github.com/sozercan/kubectl-ai) uses AI to create manifests and apply them to the
cluster. It is not what we are trying to do here, it is focusing on writing YAML manifests.
K8sgpt is focused on triaging and diagnosing issues in your cluster. It is a tool for SRE, Platform & DevOps engineers to help them understand what is going on in their cluster. Cutting through the noise of logs and multiple tools to find the root cause of an issue.
K8sgpt is focused on triaging and diagnosing issues in your cluster. It is a tool for SRE, Platform & DevOps engineers
to help them understand what is going on in their cluster. Cutting through the noise of logs and multiple tools to find
the root cause of an issue.
### Configuration
## Configuration
`k8sgpt` stores config data in `~/.k8sgpt` the data is stored in plain text, including your OpenAI key.
`k8sgpt` stores config data in `~/.k8sgpt.yaml` the data is stored in plain text, including your OpenAI key.
### Contributing
## Contributing
Please read our [contributing guide](./CONTRIBUTING.md).
### Community
* Find us on [Slack](https://cloud-native.slack.com/channels/k8sgpt-ai)
## Community
* Find us on [Slack](https://k8sgpt.slack.com/)

11
SECURITY.md Normal file
View File

@@ -0,0 +1,11 @@
# Security Policy
## Supported Versions
We currently support the latest release for security patching and will deploy forward releases.
For example if there is a vulnerability in release `0.1.0` we will fix that release in version `0.1.1-fix` or `0.1.1`
## Reporting a Vulnerability
If you are aware of a vulnverability please feel free to disclose it responsibly to contact@k8sgpt.ai or to one of our maintainers in our Slack community.

View File

@@ -17,19 +17,22 @@ import (
)
var (
explain bool
backend string
output string
filters []string
language string
explain bool
backend string
output string
filters []string
language string
nocache bool
namespace string
)
// AnalyzeCmd represents the problems command
var AnalyzeCmd = &cobra.Command{
Use: "analyze",
Short: "This command will find problems within your Kubernetes cluster",
Use: "analyze",
Aliases: []string{"analyse"},
Short: "This command will find problems within your Kubernetes cluster",
Long: `This command will find problems within your Kubernetes cluster and
provide you with a list of issues that need to be resolved`,
provide you with a list of issues that need to be resolved`,
Run: func(cmd *cobra.Command, args []string) {
// get backend from file
@@ -66,24 +69,19 @@ var AnalyzeCmd = &cobra.Command{
ctx := context.Background()
// Get kubernetes client from viper
client := viper.Get("kubernetesClient").(*kubernetes.Client)
// Analysis configuration
config := &analyzer.AnalysisConfiguration{
Namespace: namespace,
NoCache: nocache,
Explain: explain,
}
var analysisResults *[]analyzer.Analysis = &[]analyzer.Analysis{}
if err := analyzer.RunAnalysis(ctx, client, aiClient, explain, analysisResults); err != nil {
if err := analyzer.RunAnalysis(ctx, filters, config, client,
aiClient, analysisResults); err != nil {
color.Red("Error: %v", err)
os.Exit(1)
}
// Removed filtered results from slice
if len(filters) > 0 {
var filteredResults []analyzer.Analysis
for _, analysis := range *analysisResults {
for _, filter := range filters {
if strings.Contains(analysis.Kind, filter) {
filteredResults = append(filteredResults, analysis)
}
}
}
analysisResults = &filteredResults
}
var bar *progressbar.ProgressBar
if len(*analysisResults) > 0 {
@@ -100,8 +98,13 @@ var AnalyzeCmd = &cobra.Command{
for _, analysis := range *analysisResults {
if explain {
parsedText, err := analyzer.ParseViaAI(ctx, aiClient, analysis.Error)
parsedText, err := analyzer.ParseViaAI(ctx, config, aiClient, analysis.Error)
if err != nil {
// Check for exhaustion
if strings.Contains(err.Error(), "status code: 429") {
color.Red("Exhausted API quota. Please try again later")
os.Exit(1)
}
color.Red("Error: %v", err)
continue
}
@@ -124,9 +127,12 @@ var AnalyzeCmd = &cobra.Command{
}
fmt.Println(string(j))
default:
fmt.Printf("%s %s(%s): %s \n%s\n", color.CyanString("%d", n),
color.YellowString(analysis.Name), color.CyanString(analysis.ParentObject),
color.RedString(analysis.Error[0]), color.GreenString(analysis.Details))
fmt.Printf("%s %s(%s)\n", color.CyanString("%d", n),
color.YellowString(analysis.Name), color.CyanString(analysis.ParentObject))
for _, err := range analysis.Error {
fmt.Printf("- %s %s\n", color.RedString("Error:"), color.RedString(err))
}
color.GreenString(analysis.Details)
}
}
},
@@ -134,9 +140,13 @@ var AnalyzeCmd = &cobra.Command{
func init() {
// namespace flag
AnalyzeCmd.Flags().StringVarP(&namespace, "namespace", "n", "", "Namespace to analyze")
// no cache flag
AnalyzeCmd.Flags().BoolVarP(&nocache, "no-cache", "c", false, "Do not use cached data")
// array of strings flag
AnalyzeCmd.Flags().StringSliceVarP(&filters, "filter", "f", []string{}, "Filter for these analzyers (e.g. Pod,PersistentVolumeClaim,Service,ReplicaSet)")
AnalyzeCmd.Flags().StringSliceVarP(&filters, "filter", "f", []string{}, "Filter for these analyzers (e.g. Pod, PersistentVolumeClaim, Service, ReplicaSet)")
// explain flag
AnalyzeCmd.Flags().BoolVarP(&explain, "explain", "e", false, "Explain the problem to me")
// add flag for backend
AnalyzeCmd.Flags().StringVarP(&backend, "backend", "b", "openai", "Backend AI provider")

View File

@@ -35,6 +35,7 @@ var AuthCmd = &cobra.Command{
// override the default backend if a flag is provided
if backend != "" {
backendType = backend
color.Green("Using %s as backend AI provider", backendType)
}
fmt.Printf("Enter %s Key: ", backendType)

71
cmd/filters/add.go Normal file
View File

@@ -0,0 +1,71 @@
package filters
import (
"os"
"strings"
"github.com/fatih/color"
"github.com/k8sgpt-ai/k8sgpt/pkg/analyzer"
"github.com/k8sgpt-ai/k8sgpt/pkg/util"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
var addCmd = &cobra.Command{
Use: "add [filter(s)]",
Short: "Adds one or more new filters.",
Long: `The add command adds one or more new filters to the default set of filters used by the analyze.`,
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
inputFilters := strings.Split(args[0], ",")
availableFilters := analyzer.ListFilters()
// Verify filter exist
invalidFilters := []string{}
for _, f := range inputFilters {
if f == "" {
color.Red("Filter cannot be empty. Please use correct syntax.")
os.Exit(1)
}
foundFilter := false
for _, filter := range availableFilters {
if filter == f {
foundFilter = true
break
}
}
if !foundFilter {
invalidFilters = append(invalidFilters, f)
}
}
if len(invalidFilters) != 0 {
color.Red("Filter %s does not exist. Please use k8sgpt filters list", strings.Join(invalidFilters, ", "))
os.Exit(1)
}
// Get defined active_filters
activeFilters := viper.GetStringSlice("active_filters")
if len(activeFilters) == 0 {
activeFilters = availableFilters
}
mergedFilters := append(activeFilters, inputFilters...)
uniqueFilters, dupplicatedFilters := util.RemoveDuplicates(mergedFilters)
// Verify dupplicate
if len(dupplicatedFilters) != 0 {
color.Red("Duplicate filters found: %s", strings.Join(dupplicatedFilters, ", "))
os.Exit(1)
}
viper.Set("active_filters", uniqueFilters)
if err := viper.WriteConfig(); err != nil {
color.Red("Error writing config file: %s", err.Error())
os.Exit(1)
}
color.Green("Filter %s added", strings.Join(inputFilters, ", "))
},
}

25
cmd/filters/filters.go Normal file
View File

@@ -0,0 +1,25 @@
package filters
import (
"github.com/spf13/cobra"
)
var FiltersCmd = &cobra.Command{
Use: "filters",
Aliases: []string{"filters"},
Short: "Manage filters for analyzing Kubernetes resources",
Long: `The filters command allows you to manage filters that are used to analyze Kubernetes resources.
You can list available filters to analyze resources.`,
Run: func(cmd *cobra.Command, args []string) {
if len(args) == 0 {
cmd.Help()
return
}
},
}
func init() {
FiltersCmd.AddCommand(listCmd)
FiltersCmd.AddCommand(addCmd)
FiltersCmd.AddCommand(removeCmd)
}

39
cmd/filters/list.go Normal file
View File

@@ -0,0 +1,39 @@
package filters
import (
"fmt"
"github.com/fatih/color"
"github.com/k8sgpt-ai/k8sgpt/pkg/analyzer"
"github.com/k8sgpt-ai/k8sgpt/pkg/util"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
var listCmd = &cobra.Command{
Use: "list",
Short: "List available filters",
Long: `The list command displays a list of available filters that can be used to analyze Kubernetes resources.`,
Run: func(cmd *cobra.Command, args []string) {
activeFilters := viper.GetStringSlice("active_filters")
availableFilters := analyzer.ListFilters()
if len(activeFilters) == 0 {
activeFilters = availableFilters
}
inactiveFilters := util.SliceDiff(availableFilters, activeFilters)
fmt.Printf(color.YellowString("Active: \n"))
for _, filter := range activeFilters {
fmt.Printf("> %s\n", color.GreenString(filter))
}
// display inactive filters
if len(inactiveFilters) != 0 {
fmt.Printf(color.YellowString("Unused: \n"))
for _, filter := range inactiveFilters {
fmt.Printf("> %s\n", color.RedString(filter))
}
}
},
}

72
cmd/filters/remove.go Normal file
View File

@@ -0,0 +1,72 @@
package filters
import (
"os"
"strings"
"github.com/fatih/color"
"github.com/k8sgpt-ai/k8sgpt/pkg/analyzer"
"github.com/k8sgpt-ai/k8sgpt/pkg/util"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
var removeCmd = &cobra.Command{
Use: "remove [filter(s)]",
Short: "Remove one or more filters.",
Long: `The add command remove one or more filters to the default set of filters used by the analyze.`,
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
inputFilters := strings.Split(args[0], ",")
// Get defined active_filters
activeFilters := viper.GetStringSlice("active_filters")
if len(activeFilters) == 0 {
activeFilters = analyzer.ListFilters()
}
// Check if input input filters is not empty
for _, f := range inputFilters {
if f == "" {
color.Red("Filter cannot be empty. Please use correct syntax.")
os.Exit(1)
}
}
// verify dupplicate filters example: k8sgpt filters remove Pod Pod
uniqueFilters, dupplicatedFilters := util.RemoveDuplicates(inputFilters)
if len(dupplicatedFilters) != 0 {
color.Red("Duplicate filters found: %s", strings.Join(dupplicatedFilters, ", "))
os.Exit(1)
}
// Verify if filter exist in config file and update default_filter
filterNotFound := []string{}
for _, filter := range uniqueFilters {
foundFilter := false
for i, f := range activeFilters {
if f == filter {
foundFilter = true
activeFilters = append(activeFilters[:i], activeFilters[i+1:]...)
break
}
}
if !foundFilter {
filterNotFound = append(filterNotFound, filter)
}
}
if len(filterNotFound) != 0 {
color.Red("Filter(s) %s does not exist in configuration file. Please use k8sgpt filters add.", strings.Join(filterNotFound, ", "))
os.Exit(1)
}
viper.Set("active_filters", activeFilters)
if err := viper.WriteConfig(); err != nil {
color.Red("Error writing config file: %s", err.Error())
os.Exit(1)
}
color.Green("Filter(s) %s removed", strings.Join(inputFilters, ", "))
},
}

View File

@@ -1,8 +1,12 @@
package cmd
import (
"github.com/k8sgpt-ai/k8sgpt/cmd/generate"
"os"
"path/filepath"
"github.com/k8sgpt-ai/k8sgpt/cmd/filters"
"github.com/k8sgpt-ai/k8sgpt/cmd/generate"
"k8s.io/client-go/util/homedir"
"github.com/fatih/color"
"github.com/k8sgpt-ai/k8sgpt/cmd/analyze"
@@ -13,10 +17,10 @@ import (
)
var (
cfgFile string
masterURL string
kubeconfig string
version string
cfgFile string
kubecontext string
kubeconfig string
version string
)
// rootCmd represents the base command when called without any subcommands
@@ -42,26 +46,20 @@ func Execute(v string) {
func init() {
cobra.OnInitialize(initConfig)
// Here you will define your flags and configuration settings.
// Cobra supports persistent flags, which, if defined here,
// will be global for your application.
var kubeconfigPath string
if home := homedir.HomeDir(); home != "" {
kubeconfigPath = filepath.Join(home, ".kube", "config")
}
rootCmd.AddCommand(auth.AuthCmd)
rootCmd.AddCommand(analyze.AnalyzeCmd)
rootCmd.AddCommand(filters.FiltersCmd)
rootCmd.AddCommand(generate.GenerateCmd)
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.k8sgpt.git.yaml)")
rootCmd.PersistentFlags().StringVar(&masterURL, "master", "", "The address of the Kubernetes API server. Overrides any value in kubeconfig. Only required if out-of-cluster.")
rootCmd.PersistentFlags().StringVar(&kubeconfig, "kubeconfig", "", "Path to a kubeconfig. Only required if out-of-cluster.")
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.k8sgpt.yaml)")
rootCmd.PersistentFlags().StringVar(&kubecontext, "kubecontext", "", "Kubernetes context to use. Only required if out-of-cluster.")
rootCmd.PersistentFlags().StringVar(&kubeconfig, "kubeconfig", kubeconfigPath, "Path to a kubeconfig. Only required if out-of-cluster.")
// Cobra also supports local flags, which will only run
// when this action is called directly.
rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
//Initialise the kubeconfig
kubernetesClient, err := kubernetes.NewClient(masterURL, kubeconfig)
if err != nil {
color.Red("Error initialising kubernetes client: %v", err)
}
viper.Set("kubernetesClient", kubernetesClient)
// rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}
@@ -83,6 +81,15 @@ func initConfig() {
viper.SafeWriteConfig()
}
//Initialise the kubeconfig
kubernetesClient, err := kubernetes.NewClient(kubecontext, kubeconfig)
if err != nil {
color.Red("Error initialising kubernetes client: %v", err)
os.Exit(1)
}
viper.Set("kubernetesClient", kubernetesClient)
viper.AutomaticEnv() // read in environment variables that match
// If a config file is found, read it in.

View File

@@ -3,14 +3,22 @@ package analyzer
import (
appsv1 "k8s.io/api/apps/v1"
v1 "k8s.io/api/core/v1"
networkingv1 "k8s.io/api/networking/v1"
)
type AnalysisConfiguration struct {
Namespace string
NoCache bool
Explain bool
}
type PreAnalysis struct {
Pod v1.Pod
FailureDetails []string
ReplicaSet appsv1.ReplicaSet
PersistentVolumeClaim v1.PersistentVolumeClaim
Endpoint v1.Endpoints
Ingress networkingv1.Ingress
}
type Analysis struct {

View File

@@ -11,37 +11,62 @@ import (
"github.com/spf13/viper"
)
func RunAnalysis(ctx context.Context, client *kubernetes.Client, aiClient ai.IAI, explain bool, analysisResults *[]Analysis) error {
var analyzerMap = map[string]func(ctx context.Context, config *AnalysisConfiguration,
client *kubernetes.Client, aiClient ai.IAI, analysisResults *[]Analysis) error{
"Pod": AnalyzePod,
"ReplicaSet": AnalyzeReplicaSet,
"PersistentVolumeClaim": AnalyzePersistentVolumeClaim,
"Service": AnalyzeEndpoints,
"Ingress": AnalyzeIngress,
}
err := AnalyzePod(ctx, client, aiClient, explain, analysisResults)
if err != nil {
return err
func RunAnalysis(ctx context.Context, filters []string, config *AnalysisConfiguration,
client *kubernetes.Client,
aiClient ai.IAI, analysisResults *[]Analysis) error {
activeFilters := viper.GetStringSlice("active_filters")
// if there are no filters selected and no active_filters then run all of them
if len(filters) == 0 && len(activeFilters) == 0 {
for _, analyzer := range analyzerMap {
if err := analyzer(ctx, config, client, aiClient, analysisResults); err != nil {
return err
}
}
return nil
}
err = AnalyzeReplicaSet(ctx, client, aiClient, explain, analysisResults)
if err != nil {
return err
// if the filters flag is specified
if len(filters) != 0 {
for _, filter := range filters {
if analyzer, ok := analyzerMap[filter]; ok {
if err := analyzer(ctx, config, client, aiClient, analysisResults); err != nil {
return err
}
}
}
return nil
}
err = AnalyzePersistentVolumeClaim(ctx, client, aiClient, explain, analysisResults)
if err != nil {
return err
}
err = AnalyzeEndpoints(ctx, client, aiClient, explain, analysisResults)
if err != nil {
return err
// use active_filters
for _, filter := range activeFilters {
if analyzer, ok := analyzerMap[filter]; ok {
if err := analyzer(ctx, config, client, aiClient, analysisResults); err != nil {
return err
}
}
}
return nil
}
func ParseViaAI(ctx context.Context, aiClient ai.IAI, prompt []string) (string, error) {
func ParseViaAI(ctx context.Context, config *AnalysisConfiguration,
aiClient ai.IAI, prompt []string) (string, error) {
// parse the text with the AI backend
inputKey := strings.Join(prompt, " ")
// Check for cached data
sEnc := base64.StdEncoding.EncodeToString([]byte(inputKey))
// find in viper cache
if viper.IsSet(sEnc) {
if viper.IsSet(sEnc) && !config.NoCache {
// retrieve data from cache
response := viper.GetString(sEnc)
if response == "" {
@@ -59,7 +84,7 @@ func ParseViaAI(ctx context.Context, aiClient ai.IAI, prompt []string) (string,
response, err := aiClient.GetCompletion(ctx, inputKey)
if err != nil {
color.Red("error getting completion: %v", err)
return "", nil
return "", err
}
if !viper.IsSet(sEnc) {
@@ -71,3 +96,11 @@ func ParseViaAI(ctx context.Context, aiClient ai.IAI, prompt []string) (string,
}
return response, nil
}
func ListFilters() []string {
keys := make([]string, 0, len(analyzerMap))
for k := range analyzerMap {
keys = append(keys, k)
}
return keys
}

View File

@@ -0,0 +1,84 @@
package analyzer
import (
"context"
"fmt"
"github.com/k8sgpt-ai/k8sgpt/pkg/ai"
"github.com/k8sgpt-ai/k8sgpt/pkg/kubernetes"
"github.com/k8sgpt-ai/k8sgpt/pkg/util"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func AnalyzeIngress(ctx context.Context, config *AnalysisConfiguration, client *kubernetes.Client, aiClient ai.IAI,
analysisResults *[]Analysis) error {
list, err := client.GetClient().NetworkingV1().Ingresses(config.Namespace).List(ctx, metav1.ListOptions{})
if err != nil {
return err
}
var preAnalysis = map[string]PreAnalysis{}
for _, ing := range list.Items {
var failures []string
// get ingressClassName
ingressClassName := ing.Spec.IngressClassName
if ingressClassName == nil {
ingClassValue := ing.Annotations["kubernetes.io/ingress.class"]
if ingClassValue == "" {
failures = append(failures, fmt.Sprintf("Ingress %s/%s does not specify an Ingress class.", ing.Namespace, ing.Name))
} else {
ingressClassName = &ingClassValue
}
}
// check if ingressclass exist
if ingressClassName != nil {
_, err := client.GetClient().NetworkingV1().IngressClasses().Get(ctx, *ingressClassName, metav1.GetOptions{})
if err != nil {
failures = append(failures, fmt.Sprintf("Ingress uses the ingress class %s which does not exist.", *ingressClassName))
}
}
// loop over rules
for _, rule := range ing.Spec.Rules {
// loop over paths
for _, path := range rule.HTTP.Paths {
_, err := client.GetClient().CoreV1().Services(ing.Namespace).Get(ctx, path.Backend.Service.Name, metav1.GetOptions{})
if err != nil {
failures = append(failures, fmt.Sprintf("Ingress uses the service %s/%s which does not exist.", ing.Namespace, path.Backend.Service.Name))
}
}
}
for _, tls := range ing.Spec.TLS {
_, err := client.GetClient().CoreV1().Secrets(ing.Namespace).Get(ctx, tls.SecretName, metav1.GetOptions{})
if err != nil {
failures = append(failures, fmt.Sprintf("Ingress uses the secret %s/%s as a TLS certificate which does not exist.", ing.Namespace, tls.SecretName))
}
}
if len(failures) > 0 {
preAnalysis[fmt.Sprintf("%s/%s", ing.Namespace, ing.Name)] = PreAnalysis{
Ingress: ing,
FailureDetails: failures,
}
}
}
for key, value := range preAnalysis {
var currentAnalysis = Analysis{
Kind: "Ingress",
Name: key,
Error: value.FailureDetails,
}
parent, _ := util.GetParent(client, value.Ingress.ObjectMeta)
currentAnalysis.ParentObject = parent
*analysisResults = append(*analysisResults, currentAnalysis)
}
return nil
}

View File

@@ -10,10 +10,11 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func AnalyzePod(ctx context.Context, client *kubernetes.Client, aiClient ai.IAI, explain bool, analysisResults *[]Analysis) error {
func AnalyzePod(ctx context.Context, config *AnalysisConfiguration,
client *kubernetes.Client, aiClient ai.IAI, analysisResults *[]Analysis) error {
// search all namespaces for pods that are not running
list, err := client.GetClient().CoreV1().Pods("").List(ctx, metav1.ListOptions{})
list, err := client.GetClient().CoreV1().Pods(config.Namespace).List(ctx, metav1.ListOptions{})
if err != nil {
return err
}

View File

@@ -10,10 +10,10 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func AnalyzePersistentVolumeClaim(ctx context.Context, client *kubernetes.Client, aiClient ai.IAI, explain bool, analysisResults *[]Analysis) error {
func AnalyzePersistentVolumeClaim(ctx context.Context, config *AnalysisConfiguration, client *kubernetes.Client, aiClient ai.IAI, analysisResults *[]Analysis) error {
// search all namespaces for pods that are not running
list, err := client.GetClient().CoreV1().PersistentVolumeClaims("").List(ctx, metav1.ListOptions{})
list, err := client.GetClient().CoreV1().PersistentVolumeClaims(config.Namespace).List(ctx, metav1.ListOptions{})
if err != nil {
return err
}

View File

@@ -10,10 +10,11 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func AnalyzeReplicaSet(ctx context.Context, client *kubernetes.Client, aiClient ai.IAI, explain bool, analysisResults *[]Analysis) error {
func AnalyzeReplicaSet(ctx context.Context, config *AnalysisConfiguration,
client *kubernetes.Client, aiClient ai.IAI, analysisResults *[]Analysis) error {
// search all namespaces for pods that are not running
list, err := client.GetClient().AppsV1().ReplicaSets("").List(ctx, metav1.ListOptions{})
list, err := client.GetClient().AppsV1().ReplicaSets(config.Namespace).List(ctx, metav1.ListOptions{})
if err != nil {
return err
}

View File

@@ -4,16 +4,18 @@ import (
"context"
"fmt"
"github.com/fatih/color"
"github.com/k8sgpt-ai/k8sgpt/pkg/ai"
"github.com/k8sgpt-ai/k8sgpt/pkg/kubernetes"
"github.com/k8sgpt-ai/k8sgpt/pkg/util"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func AnalyzeEndpoints(ctx context.Context, client *kubernetes.Client, aiClient ai.IAI, explain bool, analysisResults *[]Analysis) error {
func AnalyzeEndpoints(ctx context.Context, config *AnalysisConfiguration, client *kubernetes.Client, aiClient ai.IAI,
analysisResults *[]Analysis) error {
// search all namespaces for pods that are not running
list, err := client.GetClient().CoreV1().Endpoints("").List(ctx, metav1.ListOptions{})
list, err := client.GetClient().CoreV1().Endpoints(config.Namespace).List(ctx, metav1.ListOptions{})
if err != nil {
return err
}
@@ -27,7 +29,8 @@ func AnalyzeEndpoints(ctx context.Context, client *kubernetes.Client, aiClient a
if len(ep.Subsets) == 0 {
svc, err := client.GetClient().CoreV1().Services(ep.Namespace).Get(ctx, ep.Name, metav1.GetOptions{})
if err != nil {
return err
color.Yellow("Service %s/%s does not exist", ep.Namespace, ep.Name)
continue
}
for k, v := range svc.Spec.Selector {

View File

@@ -2,7 +2,6 @@ package kubernetes
import (
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
)
@@ -14,21 +13,23 @@ func (c *Client) GetClient() *kubernetes.Clientset {
return c.client
}
func NewClient(masterURL string, kubeconfig string) (*Client, error) {
func NewClient(kubecontext string, kubeconfig string) (*Client, error) {
config, err := rest.InClusterConfig()
if err != nil {
kubeconfig :=
clientcmd.NewDefaultClientConfigLoadingRules().GetDefaultFilename()
config, err = clientcmd.BuildConfigFromFlags(masterURL, kubeconfig)
if err != nil {
return nil, err
}
}
clientSet, err := kubernetes.NewForConfig(config)
config := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
&clientcmd.ClientConfigLoadingRules{ExplicitPath: kubeconfig},
&clientcmd.ConfigOverrides{
CurrentContext: kubecontext,
})
// create the clientset
c, err := config.ClientConfig()
if err != nil {
return nil, err
}
clientSet, err := kubernetes.NewForConfig(c)
if err != nil {
return nil, err
}
return &Client{
client: clientSet,
}, nil

View File

@@ -50,8 +50,49 @@ func GetParent(client *kubernetes.Client, meta metav1.ObjectMeta) (string, bool)
return GetParent(client, ds.ObjectMeta)
}
return "DaemonSet/" + ds.Name, false
case "Ingress":
ds, err := client.GetClient().NetworkingV1().Ingresses(meta.Namespace).Get(context.Background(), owner.Name, metav1.GetOptions{})
if err != nil {
return "", false
}
if ds.OwnerReferences != nil {
return GetParent(client, ds.ObjectMeta)
}
return "Ingress/" + ds.Name, false
}
}
}
return meta.Name, false
}
func RemoveDuplicates(slice []string) ([]string, []string) {
set := make(map[string]bool)
duplicates := []string{}
for _, val := range slice {
if _, ok := set[val]; !ok {
set[val] = true
} else {
duplicates = append(duplicates, val)
}
}
uniqueSlice := make([]string, 0, len(set))
for val := range set {
uniqueSlice = append(uniqueSlice, val)
}
return uniqueSlice, duplicates
}
func SliceDiff(source, dest []string) []string {
mb := make(map[string]struct{}, len(dest))
for _, x := range dest {
mb[x] = struct{}{}
}
var diff []string
for _, x := range source {
if _, found := mb[x]; !found {
diff = append(diff, x)
}
}
return diff
}