Compare commits

..

1 Commits

Author SHA1 Message Date
Alex Jones
2b14cae5a6 example of an integration
Signed-off-by: Alex Jones <alexsimonjones@gmail.com>
2023-06-15 12:15:02 +01:00
57 changed files with 737 additions and 2924 deletions

View File

@@ -33,7 +33,7 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3
- name: Extract branch name
id: extract_branch
@@ -70,14 +70,14 @@ jobs:
RELEASE_REGISTRY: "localhost:5000/k8sgpt"
steps:
- name: Check out code
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3
uses: docker/setup-buildx-action@6a58db7e0d21ca03e6c44877909e80e45217eed2 # v2
- name: Build Docker Image
uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5
uses: docker/build-push-action@44ea916f6c540f9302d50c2b1e5a8dc071f15cdf # v4
with:
context: .
platforms: linux/amd64
@@ -96,7 +96,7 @@ jobs:
outputs: type=docker,dest=/tmp/${{ env.IMAGE_NAME }}-image.tar
- name: Upload image as artifact
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3
with:
name: ${{ env.IMAGE_NAME }}-image.tar
path: /tmp/${{ env.IMAGE_NAME }}-image.tar
@@ -115,10 +115,10 @@ jobs:
contents: read # Needed for checking out the repository
steps:
- name: Check out code
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3
- name: Login to GitHub Container Registry
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3
uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a # v2
with:
registry: "ghcr.io"
username: ${{ github.actor }}
@@ -126,10 +126,10 @@ jobs:
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3
uses: docker/setup-buildx-action@6a58db7e0d21ca03e6c44877909e80e45217eed2 # v2
- name: Build Docker Image
uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5
uses: docker/build-push-action@44ea916f6c540f9302d50c2b1e5a8dc071f15cdf # v4
with:
context: .
file: ./container/Dockerfile

View File

@@ -9,10 +9,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Check out code into the Go module directory
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3
- name: golangci-lint
uses: reviewdog/action-golangci-lint@24d4af2fc93f5b2b296229e8b0c0f658d25707af # v2
uses: reviewdog/action-golangci-lint@79d32f10b2ea0d4cebb755d849b048c4b40c3d50 # v2
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
reporter: github-pr-check

View File

@@ -23,9 +23,9 @@ jobs:
# Release-please creates a PR that tracks all changes
steps:
- name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3
- uses: google-github-actions/release-please-action@ca6063f4ed81b55db15b8c42d1b6f7925866342d # v3
- uses: google-github-actions/release-please-action@51ee8ae2605bd5ce1cfdcc5938684908f1cd9f69 # v3
id: release
with:
command: manifest
@@ -41,17 +41,17 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4
uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4
with:
go-version: '1.20'
- name: Download Syft
uses: anchore/sbom-action/download-syft@78fc58e266e87a38d4194b2137a3d4e9bcaf7ca1 # v0.14.3
uses: anchore/sbom-action/download-syft@4d571ad1038a9cc29d676154ef265ab8f9027042 # v0.14.2
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@7ec5c2b0c6cdda6e8bbb49444bc797dd33d74dd8 # v5
uses: goreleaser/goreleaser-action@336e29918d653399e599bfca99fadc1d7ffbc9f7 # v4
with:
# either 'goreleaser' (default) or 'goreleaser-pro'
distribution: goreleaser
@@ -74,23 +74,23 @@ jobs:
IMAGE_NAME: k8sgpt
steps:
- name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3
with:
submodules: recursive
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3
uses: docker/setup-buildx-action@6a58db7e0d21ca03e6c44877909e80e45217eed2 # v2
- name: Login to GitHub Container Registry
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3
uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a # v2
with:
registry: "ghcr.io"
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build Docker Image
uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5
uses: docker/build-push-action@44ea916f6c540f9302d50c2b1e5a8dc071f15cdf # v4
with:
context: .
file: ./container/Dockerfile
@@ -104,7 +104,7 @@ jobs:
cache-to: type=gha,scope=${{ github.ref_name }}-${{ env.IMAGE_TAG }}
- name: Generate SBOM
uses: anchore/sbom-action@78fc58e266e87a38d4194b2137a3d4e9bcaf7ca1 # v0.14.3
uses: anchore/sbom-action@4d571ad1038a9cc29d676154ef265ab8f9027042 # v0.14.2
with:
image: ${{ env.IMAGE_TAG }}
artifact-name: sbom-${{ env.IMAGE_NAME }}

View File

@@ -16,7 +16,7 @@ jobs:
pull-requests: read # Needed for reading prs
steps:
- name: Validate Pull Request
uses: amannn/action-semantic-pull-request@e9fabac35e210fea40ca5b14c0da95a099eff26f # v5.4.0
uses: amannn/action-semantic-pull-request@c3cd5d1ea3580753008872425915e343e351ab54 # v5.2.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:

View File

@@ -16,10 +16,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3
- name: Set up Go
uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4
uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4
with:
go-version: ${{ env.GO_VERSION }}

2
.gitignore vendored
View File

@@ -1,5 +1,3 @@
.idea
__debug*
.DS_Store
k8sgpt*
!charts/k8sgpt

View File

@@ -1 +1 @@
{".":"0.3.20"}
{".":"0.3.7"}

View File

@@ -1,332 +1,5 @@
# Changelog
## [0.3.20](https://github.com/k8sgpt-ai/k8sgpt/compare/v0.3.19...v0.3.20) (2023-11-05)
### Features
* amazonsagemaker AI provider ([#731](https://github.com/k8sgpt-ai/k8sgpt/issues/731)) ([ccef7f6](https://github.com/k8sgpt-ai/k8sgpt/commit/ccef7f617004723b37d1e8ffb011398005e0b392))
### Bug Fixes
* **deps:** update module github.com/aws/aws-sdk-go to v1.47.1 ([#724](https://github.com/k8sgpt-ai/k8sgpt/issues/724)) ([0136b8f](https://github.com/k8sgpt-ai/k8sgpt/commit/0136b8f543a7052e967e29691afe1aab8e5fae1b))
* **deps:** update module github.com/azure/azure-sdk-for-go/sdk/storage/azblob to v1.2.0 ([#723](https://github.com/k8sgpt-ai/k8sgpt/issues/723)) ([16b229d](https://github.com/k8sgpt-ai/k8sgpt/commit/16b229d5478085655041ff0230d2542c4c0c7ce9))
* **deps:** update module google.golang.org/grpc to v1.59.0 ([#713](https://github.com/k8sgpt-ai/k8sgpt/issues/713)) ([901c5ec](https://github.com/k8sgpt-ai/k8sgpt/commit/901c5ec18858f2f7fd385ff20aef77d203748c93))
* **deps:** update module helm.sh/helm/v3 to v3.13.1 ([#706](https://github.com/k8sgpt-ai/k8sgpt/issues/706)) ([40133ad](https://github.com/k8sgpt-ai/k8sgpt/commit/40133adaedff3862199e00f62877a88fcffa67c5))
* ensure ingress HTTP rule exists to prevent panic ([#726](https://github.com/k8sgpt-ai/k8sgpt/issues/726)) ([37721b5](https://github.com/k8sgpt-ai/k8sgpt/commit/37721b5dd77d66edfb7e8377b2b96470b8a21d1b))
### Other
* **deps:** update amannn/action-semantic-pull-request action to v5.4.0 ([#729](https://github.com/k8sgpt-ai/k8sgpt/issues/729)) ([188a8a2](https://github.com/k8sgpt-ai/k8sgpt/commit/188a8a2cd5e25b35446e2eab46279a0ba3976af3))
## [0.3.19](https://github.com/k8sgpt-ai/k8sgpt/compare/v0.3.18...v0.3.19) (2023-10-28)
### Features
* add amazonbedrock ([#718](https://github.com/k8sgpt-ai/k8sgpt/issues/718)) ([f1a7801](https://github.com/k8sgpt-ai/k8sgpt/commit/f1a7801e9e6a7e4a5310622951dfba3ba3acd047))
* add Azure remote cache ([#690](https://github.com/k8sgpt-ai/k8sgpt/issues/690)) ([23ac52d](https://github.com/k8sgpt-ai/k8sgpt/commit/23ac52d5ffc0b2ebb7516b070fa740108cb4299a))
### Bug Fixes
* **deps:** update kubernetes packages to v0.28.3 ([#715](https://github.com/k8sgpt-ai/k8sgpt/issues/715)) ([7e73f8a](https://github.com/k8sgpt-ai/k8sgpt/commit/7e73f8afbce7ba0e9de432671b88c01fcfe28c3a))
* **deps:** update module github.com/aws/aws-sdk-go to v1.45.25 ([#707](https://github.com/k8sgpt-ai/k8sgpt/issues/707)) ([3ebc867](https://github.com/k8sgpt-ai/k8sgpt/commit/3ebc86772dc8f8cb2d2246724f5fd05d1e931512))
* **deps:** update module github.com/aws/aws-sdk-go to v1.45.26 ([#709](https://github.com/k8sgpt-ai/k8sgpt/issues/709)) ([c977528](https://github.com/k8sgpt-ai/k8sgpt/commit/c977528ec7839902570785e0803f6c6b83a0a69d))
* **deps:** update module github.com/aws/aws-sdk-go to v1.46.5 ([#712](https://github.com/k8sgpt-ai/k8sgpt/issues/712)) ([63a2260](https://github.com/k8sgpt-ai/k8sgpt/commit/63a226065c8068f9bdc0aa791a325fa10bba3fcc))
* **deps:** update module github.com/azure/azure-sdk-for-go/sdk/azidentity to v1.4.0 ([#722](https://github.com/k8sgpt-ai/k8sgpt/issues/722)) ([0e7219a](https://github.com/k8sgpt-ai/k8sgpt/commit/0e7219a36aaa718b7d86adf0a218a521bfac119b))
* **deps:** update module github.com/sashabaranov/go-openai to v1.16.0 ([#703](https://github.com/k8sgpt-ai/k8sgpt/issues/703)) ([b5facd6](https://github.com/k8sgpt-ai/k8sgpt/commit/b5facd64a340a96d38faf045bbb889b928ef08a1))
* **deps:** update module github.com/spf13/viper to v1.17.0 ([#700](https://github.com/k8sgpt-ai/k8sgpt/issues/700)) ([184d148](https://github.com/k8sgpt-ai/k8sgpt/commit/184d1481081f4297bec21fbd60d7eff1964944ae))
* **deps:** update module google.golang.org/grpc to v1.58.3 ([#704](https://github.com/k8sgpt-ai/k8sgpt/issues/704)) ([1d7360c](https://github.com/k8sgpt-ai/k8sgpt/commit/1d7360c0ae4dab376872acc71dc68d59eb4d9752))
### Other
* **deps:** update actions/checkout digest to b4ffde6 ([#719](https://github.com/k8sgpt-ai/k8sgpt/issues/719)) ([a77bd41](https://github.com/k8sgpt-ai/k8sgpt/commit/a77bd410489e624d29ccc8fd45a004f6844b3620))
* **deps:** update module oras.land/oras-go to v1.2.4 ([#665](https://github.com/k8sgpt-ai/k8sgpt/issues/665)) ([4af0ad0](https://github.com/k8sgpt-ai/k8sgpt/commit/4af0ad0303d9b0ffb43f1e87fb5abe279d9a8724))
## [0.3.18](https://github.com/k8sgpt-ai/k8sgpt/compare/v0.3.17...v0.3.18) (2023-10-12)
### Features
* adding temperature to server mode ([#705](https://github.com/k8sgpt-ai/k8sgpt/issues/705)) ([539ca3b](https://github.com/k8sgpt-ai/k8sgpt/commit/539ca3b78f96694c11f788255d3b83d2fb335df4))
### Bug Fixes
* **deps:** update module buf.build/gen/go/k8sgpt-ai/k8sgpt/grpc/go to v1.3.0-20231002095256-194bc640518b.1 ([#692](https://github.com/k8sgpt-ai/k8sgpt/issues/692)) ([4d4e33b](https://github.com/k8sgpt-ai/k8sgpt/commit/4d4e33bea9cc4f5f9bf5379db5b890d9ba86e0a9))
* **deps:** update module buf.build/gen/go/k8sgpt-ai/k8sgpt/protocolbuffers/go to v1.31.0-20231002095256-194bc640518b.1 ([#693](https://github.com/k8sgpt-ai/k8sgpt/issues/693)) ([20e6bd8](https://github.com/k8sgpt-ai/k8sgpt/commit/20e6bd816f636d4e4c8274d417870ec28fdd8a56))
* **deps:** update module github.com/aws/aws-sdk-go to v1.45.20 ([#685](https://github.com/k8sgpt-ai/k8sgpt/issues/685)) ([2494946](https://github.com/k8sgpt-ai/k8sgpt/commit/2494946dc867a532460bd6aac74dfb7da5184c1c))
* **deps:** update module github.com/aws/aws-sdk-go to v1.45.21 ([#696](https://github.com/k8sgpt-ai/k8sgpt/issues/696)) ([95c8cc0](https://github.com/k8sgpt-ai/k8sgpt/commit/95c8cc0afb0bb7b99784dcc5ba155f94b5a7dbdf))
* **deps:** update module github.com/aws/aws-sdk-go to v1.45.22 ([#697](https://github.com/k8sgpt-ai/k8sgpt/issues/697)) ([923a8c1](https://github.com/k8sgpt-ai/k8sgpt/commit/923a8c13c06b152d04e8b00ab002e2036bf12740))
* **deps:** update module github.com/aws/aws-sdk-go to v1.45.23 ([#699](https://github.com/k8sgpt-ai/k8sgpt/issues/699)) ([3f36a44](https://github.com/k8sgpt-ai/k8sgpt/commit/3f36a4441532e3d0ac1bd9d00fc738d4902b23a8))
* **deps:** update module github.com/aws/aws-sdk-go to v1.45.24 ([#701](https://github.com/k8sgpt-ai/k8sgpt/issues/701)) ([6d3038b](https://github.com/k8sgpt-ai/k8sgpt/commit/6d3038b0e8336235dc6a2fdb69d2381790331596))
* **deps:** update module github.com/prometheus/client_golang to v1.17.0 ([#687](https://github.com/k8sgpt-ai/k8sgpt/issues/687)) ([9597002](https://github.com/k8sgpt-ai/k8sgpt/commit/95970027237e0079ed1f66dc9655fa01b181f4d7))
* **deps:** update module github.com/sashabaranov/go-openai to v1.15.4 ([#689](https://github.com/k8sgpt-ai/k8sgpt/issues/689)) ([f11d314](https://github.com/k8sgpt-ai/k8sgpt/commit/f11d3149b228b643155ed66c189cb0f8a4dd5a0f))
* **deps:** update module helm.sh/helm/v3 to v3.13.0 ([#688](https://github.com/k8sgpt-ai/k8sgpt/issues/688)) ([87c8bce](https://github.com/k8sgpt-ai/k8sgpt/commit/87c8bcea4becd165aeb0ac98d79df7dab9c37ee3))
* security warning around printing provider details in https://github.com/k8sgpt-ai/k8sgpt/security/code-scanning/1 ([#695](https://github.com/k8sgpt-ai/k8sgpt/issues/695)) ([85ce557](https://github.com/k8sgpt-ai/k8sgpt/commit/85ce55768199f90b1d2a5118ec2621ea5c7a7a67))
### Other
* **deps:** update amannn/action-semantic-pull-request action to v5.3.0 ([#683](https://github.com/k8sgpt-ai/k8sgpt/issues/683)) ([c5a8c46](https://github.com/k8sgpt-ai/k8sgpt/commit/c5a8c462989c097bf37ac48ea4f1a9010285042c))
* fixing default model issue ([#702](https://github.com/k8sgpt-ai/k8sgpt/issues/702)) ([2a34ff2](https://github.com/k8sgpt-ai/k8sgpt/commit/2a34ff24d1f391270ae42531807cb1422880ad27))
## [0.3.17](https://github.com/k8sgpt-ai/k8sgpt/compare/v0.3.16...v0.3.17) (2023-09-28)
### Features
* added create namespace on deploy ([#673](https://github.com/k8sgpt-ai/k8sgpt/issues/673)) ([820e475](https://github.com/k8sgpt-ai/k8sgpt/commit/820e4755a54ecab3b5d800017bf6948dc9212825))
* integration refactor ([#684](https://github.com/k8sgpt-ai/k8sgpt/issues/684)) ([69fe2db](https://github.com/k8sgpt-ai/k8sgpt/commit/69fe2db8acb795add27f04c1c8ee8d05819300ac))
* update readme with new analyzers ([#671](https://github.com/k8sgpt-ai/k8sgpt/issues/671)) ([cad605a](https://github.com/k8sgpt-ai/k8sgpt/commit/cad605af462ce8b02ffc279ea847e41b7a64196f))
### Bug Fixes
* **deps:** update kubernetes packages to v0.28.2 ([#607](https://github.com/k8sgpt-ai/k8sgpt/issues/607)) ([ddeff9f](https://github.com/k8sgpt-ai/k8sgpt/commit/ddeff9fae4e80d1452893c59b89742633eb6b51b))
* **deps:** update module github.com/aws/aws-sdk-go to v1.45.14 ([#672](https://github.com/k8sgpt-ai/k8sgpt/issues/672)) ([1da4b7c](https://github.com/k8sgpt-ai/k8sgpt/commit/1da4b7c8f0eee877d5b76a7dd9abda7631d922f3))
* **deps:** update module github.com/aws/aws-sdk-go to v1.45.16 ([#682](https://github.com/k8sgpt-ai/k8sgpt/issues/682)) ([e1a42ff](https://github.com/k8sgpt-ai/k8sgpt/commit/e1a42ff3bcb3ddea71df2a5b5288eade024684dc))
* **deps:** update module github.com/google/gnostic to v0.7.0 ([#679](https://github.com/k8sgpt-ai/k8sgpt/issues/679)) ([901ffb8](https://github.com/k8sgpt-ai/k8sgpt/commit/901ffb8df451ce41e6dc96da61deab987e51b6df))
* **deps:** update module google.golang.org/grpc to v1.58.2 ([#680](https://github.com/k8sgpt-ai/k8sgpt/issues/680)) ([402e97d](https://github.com/k8sgpt-ai/k8sgpt/commit/402e97d05ea33879d997d98019b72da0f1074fc7))
### Other
* **deps:** update actions/checkout digest to 8ade135 ([#681](https://github.com/k8sgpt-ai/k8sgpt/issues/681)) ([aa9e6a3](https://github.com/k8sgpt-ai/k8sgpt/commit/aa9e6a3549877260423462c35ebbdfd95381be2c))
## [0.3.16](https://github.com/k8sgpt-ai/k8sgpt/compare/v0.3.15...v0.3.16) (2023-09-19)
### Features
* lists activate integrations ([#669](https://github.com/k8sgpt-ai/k8sgpt/issues/669)) ([844ff1f](https://github.com/k8sgpt-ai/k8sgpt/commit/844ff1fc78e7c35837c08b72bd2c19e92698d53d))
* openAI explicit value for maxToken and temperature ([#659](https://github.com/k8sgpt-ai/k8sgpt/issues/659)) ([f55946d](https://github.com/k8sgpt-ai/k8sgpt/commit/f55946d60ebc7725aba6702570ca1cb5ba978d78))
* serve/integration capability ([#645](https://github.com/k8sgpt-ai/k8sgpt/issues/645)) ([ab064b9](https://github.com/k8sgpt-ai/k8sgpt/commit/ab064b940cdb39a1588816221b20191e68263c61))
### Bug Fixes
* **deps:** update module buf.build/gen/go/k8sgpt-ai/k8sgpt/grpc/go to v1.3.0-20230830164712-dc062a152c20.1 ([#617](https://github.com/k8sgpt-ai/k8sgpt/issues/617)) ([d6b7b81](https://github.com/k8sgpt-ai/k8sgpt/commit/d6b7b818aef1b7775d1e76231077b74481546c56))
* **deps:** update module github.com/aws/aws-sdk-go to v1.45.10 ([#657](https://github.com/k8sgpt-ai/k8sgpt/issues/657)) ([0325724](https://github.com/k8sgpt-ai/k8sgpt/commit/03257246589ebbb22961e13394e49b52cb056e38))
* **deps:** update module github.com/aws/aws-sdk-go to v1.45.11 ([#662](https://github.com/k8sgpt-ai/k8sgpt/issues/662)) ([1b80b0c](https://github.com/k8sgpt-ai/k8sgpt/commit/1b80b0ce95f39c1cf27ad8bbb05a7fed10322114))
* **deps:** update module github.com/aws/aws-sdk-go to v1.45.12 ([#666](https://github.com/k8sgpt-ai/k8sgpt/issues/666)) ([b4656f5](https://github.com/k8sgpt-ai/k8sgpt/commit/b4656f533bdf39d12b223158bf41087076fa6c9a))
* **deps:** update module github.com/sashabaranov/go-openai to v1.15.3 ([#636](https://github.com/k8sgpt-ai/k8sgpt/issues/636)) ([54caff8](https://github.com/k8sgpt-ai/k8sgpt/commit/54caff837dc25ae594c6cd0e1bd0b31b1612cf73))
* **deps:** update module go.uber.org/zap to v1.26.0 ([#658](https://github.com/k8sgpt-ai/k8sgpt/issues/658)) ([f76b572](https://github.com/k8sgpt-ai/k8sgpt/commit/f76b57265432a704c3fc5aa67b0d569179b4ef03))
* **deps:** update module google.golang.org/grpc to v1.58.0 ([#635](https://github.com/k8sgpt-ai/k8sgpt/issues/635)) ([d58e002](https://github.com/k8sgpt-ai/k8sgpt/commit/d58e002d7dc55cc759402fcadb03af921cd30dc3))
* **deps:** update module google.golang.org/grpc to v1.58.1 ([#656](https://github.com/k8sgpt-ai/k8sgpt/issues/656)) ([abfb584](https://github.com/k8sgpt-ai/k8sgpt/commit/abfb58432fbd1168db13880e5b9dbcbdde70f147))
* emergency fix for bad package revision in go mod ([#663](https://github.com/k8sgpt-ai/k8sgpt/issues/663)) ([2472da1](https://github.com/k8sgpt-ai/k8sgpt/commit/2472da167300a831dc5b45f7fc0169a0b5b1ccb7))
* pdb panic error guard ([#664](https://github.com/k8sgpt-ai/k8sgpt/issues/664)) ([3277b2a](https://github.com/k8sgpt-ai/k8sgpt/commit/3277b2ad4b27ade9bd7da07f5fc8d8f074355177))
* respect namespace scope in trivy analyzer ([#661](https://github.com/k8sgpt-ai/k8sgpt/issues/661)) ([6481590](https://github.com/k8sgpt-ai/k8sgpt/commit/6481590b29b80391ea1c9298cae5d8f0a4ae7354))
* use default values when adding auth ([#568](https://github.com/k8sgpt-ai/k8sgpt/issues/568)) ([7461a74](https://github.com/k8sgpt-ai/k8sgpt/commit/7461a748f8e994e58ac4f56fd9919b1744bd7366)), closes [#567](https://github.com/k8sgpt-ai/k8sgpt/issues/567)
### Other
* **deps:** update actions/upload-artifact digest to a8a3f3a ([#633](https://github.com/k8sgpt-ai/k8sgpt/issues/633)) ([4bfc7f9](https://github.com/k8sgpt-ai/k8sgpt/commit/4bfc7f996c851adadc5ab0754da6852979084e9d))
* **deps:** update reviewdog/action-golangci-lint digest to 24d4af2 ([#642](https://github.com/k8sgpt-ai/k8sgpt/issues/642)) ([f607360](https://github.com/k8sgpt-ai/k8sgpt/commit/f60736035b2601650f4b3ee352f16d1e57d6ec64))
## [0.3.15](https://github.com/k8sgpt-ai/k8sgpt/compare/v0.3.14...v0.3.15) (2023-09-14)
### Features
* show each ConfigAuditReport check ([#646](https://github.com/k8sgpt-ai/k8sgpt/issues/646)) ([230eace](https://github.com/k8sgpt-ai/k8sgpt/commit/230eace18737a81e4c023826ffef1a9b1e17d4fd))
### Bug Fixes
* defer to service analyser when selectors are missing ([#652](https://github.com/k8sgpt-ai/k8sgpt/issues/652)) ([6c5a062](https://github.com/k8sgpt-ai/k8sgpt/commit/6c5a0628e4a8c493beae85049448e6e6588d63be))
* **deps:** update module github.com/aws/aws-sdk-go to v1.44.333 ([#611](https://github.com/k8sgpt-ai/k8sgpt/issues/611)) ([96d97cf](https://github.com/k8sgpt-ai/k8sgpt/commit/96d97cfa30c4d3c75facda3d3016c080dfa86eaa))
* **deps:** update module github.com/aws/aws-sdk-go to v1.45.0 ([#618](https://github.com/k8sgpt-ai/k8sgpt/issues/618)) ([632fc9a](https://github.com/k8sgpt-ai/k8sgpt/commit/632fc9a99fd0482dcff0768211c49bffb2e4032a))
* **deps:** update module github.com/aws/aws-sdk-go to v1.45.1 ([#624](https://github.com/k8sgpt-ai/k8sgpt/issues/624)) ([09984c2](https://github.com/k8sgpt-ai/k8sgpt/commit/09984c245de40fc7794f85a9535af4f8e5f5e776))
* **deps:** update module github.com/aws/aws-sdk-go to v1.45.2 ([#625](https://github.com/k8sgpt-ai/k8sgpt/issues/625)) ([b6498ef](https://github.com/k8sgpt-ai/k8sgpt/commit/b6498ef269919c61004dd860ebf08ed7f28810f7))
* **deps:** update module github.com/aws/aws-sdk-go to v1.45.3 ([#632](https://github.com/k8sgpt-ai/k8sgpt/issues/632)) ([5f73240](https://github.com/k8sgpt-ai/k8sgpt/commit/5f73240a0615e58a37e9eb00784628621bc1dfa1))
* **deps:** update module github.com/aws/aws-sdk-go to v1.45.6 ([#634](https://github.com/k8sgpt-ai/k8sgpt/issues/634)) ([3aabb48](https://github.com/k8sgpt-ai/k8sgpt/commit/3aabb4842d96ec14e61842847dc2feb3e3f31a0a))
* **deps:** update module github.com/aws/aws-sdk-go to v1.45.9 ([#640](https://github.com/k8sgpt-ai/k8sgpt/issues/640)) ([95787f2](https://github.com/k8sgpt-ai/k8sgpt/commit/95787f2854c4e4a971b2d687d97a5ceca30b9d5e))
* **deps:** update module github.com/sashabaranov/go-openai to v1.15.1 ([#622](https://github.com/k8sgpt-ai/k8sgpt/issues/622)) ([fc90dc8](https://github.com/k8sgpt-ai/k8sgpt/commit/fc90dc865b48fae99253b8bb6a8b1ae7047170b4))
* **deps:** update module golang.org/x/term to v0.12.0 ([#626](https://github.com/k8sgpt-ai/k8sgpt/issues/626)) ([44d17c5](https://github.com/k8sgpt-ai/k8sgpt/commit/44d17c51ff8ece92cd0c85f40d15caa97d990544))
* typos ([#629](https://github.com/k8sgpt-ai/k8sgpt/issues/629)) ([067c348](https://github.com/k8sgpt-ai/k8sgpt/commit/067c3483e6b379bd710c7f799de63bc1890b6c81))
* use-case while in cluster, connecting to an external ([#623](https://github.com/k8sgpt-ai/k8sgpt/issues/623)) ([1a7f45c](https://github.com/k8sgpt-ai/k8sgpt/commit/1a7f45cc55348d567148d01e61c7527e4d534f34))
### Other
* **deps:** bump github.com/cyphar/filepath-securejoin ([#644](https://github.com/k8sgpt-ai/k8sgpt/issues/644)) ([25890e6](https://github.com/k8sgpt-ai/k8sgpt/commit/25890e6e3807171e655fec0d2081cedad3ad6273))
* **deps:** update actions/checkout action to v4 ([#628](https://github.com/k8sgpt-ai/k8sgpt/issues/628)) ([e65d9a6](https://github.com/k8sgpt-ai/k8sgpt/commit/e65d9a650522120d602b2a62703aa2b39abfdea1))
* **deps:** update actions/checkout digest to f43a0e5 ([#612](https://github.com/k8sgpt-ai/k8sgpt/issues/612)) ([6f9f7b2](https://github.com/k8sgpt-ai/k8sgpt/commit/6f9f7b2b602605f3be7fd02bd521574e9c26fa78))
* **deps:** update docker/build-push-action action to v5 ([#643](https://github.com/k8sgpt-ai/k8sgpt/issues/643)) ([241f1bd](https://github.com/k8sgpt-ai/k8sgpt/commit/241f1bd6dfcb772711551aac42e48a2f59e64046))
* **deps:** update docker/login-action action to v3 ([#648](https://github.com/k8sgpt-ai/k8sgpt/issues/648)) ([b491c92](https://github.com/k8sgpt-ai/k8sgpt/commit/b491c9200e781284737dd74a9789dfc0c1e7b14a))
* **deps:** update docker/setup-buildx-action action to v3 ([#649](https://github.com/k8sgpt-ai/k8sgpt/issues/649)) ([598ef22](https://github.com/k8sgpt-ai/k8sgpt/commit/598ef22e570c1db678d583638c83e242f3b313d7))
* **deps:** update docker/setup-buildx-action digest to 885d146 ([#615](https://github.com/k8sgpt-ai/k8sgpt/issues/615)) ([2c81dad](https://github.com/k8sgpt-ai/k8sgpt/commit/2c81dadb4d4abcdc3608be768c1f3aae87e53a68))
* **deps:** update goreleaser/goreleaser-action action to v5 ([#641](https://github.com/k8sgpt-ai/k8sgpt/issues/641)) ([00d7a27](https://github.com/k8sgpt-ai/k8sgpt/commit/00d7a27ec1ea1bd49ab1879b8ffa0b9e7c0b6adf))
* **deps:** update goreleaser/goreleaser-action digest to 5fdedb9 ([#631](https://github.com/k8sgpt-ai/k8sgpt/issues/631)) ([5de3b64](https://github.com/k8sgpt-ai/k8sgpt/commit/5de3b640988783df5a04db368f79b9b9eefdb8bf))
* fixes a bug where filters do not deactive ([#621](https://github.com/k8sgpt-ai/k8sgpt/issues/621)) ([133850f](https://github.com/k8sgpt-ai/k8sgpt/commit/133850f984cc0bb41ec1e4521a32ab30558778f1))
* slice loop replace ([#627](https://github.com/k8sgpt-ai/k8sgpt/issues/627)) ([c24825b](https://github.com/k8sgpt-ai/k8sgpt/commit/c24825b81025c5cd79224a79b52d6c5efdc00511))
* updated protobuf libs ([#614](https://github.com/k8sgpt-ai/k8sgpt/issues/614)) ([5e17e66](https://github.com/k8sgpt-ai/k8sgpt/commit/5e17e666659c0eb057562def70d491daa995e5a2))
* updated schema for integrations support ([#616](https://github.com/k8sgpt-ai/k8sgpt/issues/616)) ([8f0a2fd](https://github.com/k8sgpt-ai/k8sgpt/commit/8f0a2fd41d6705da4d1a1d288f3b6ce19711f30d))
## [0.3.14](https://github.com/k8sgpt-ai/k8sgpt/compare/v0.3.13...v0.3.14) (2023-08-25)
### Features
* configauditreport ([#609](https://github.com/k8sgpt-ai/k8sgpt/issues/609)) ([44d3613](https://github.com/k8sgpt-ai/k8sgpt/commit/44d3613c1f950837c6b112ddde0dc3e90f73dc1b))
### Bug Fixes
* **deps:** update kubernetes packages to v0.27.4 ([#565](https://github.com/k8sgpt-ai/k8sgpt/issues/565)) ([3cc7aa5](https://github.com/k8sgpt-ai/k8sgpt/commit/3cc7aa56d8efc6e78badf3be1cb3d5726074156e))
* **deps:** update module github.com/aquasecurity/trivy-operator to v0.15.1 ([#576](https://github.com/k8sgpt-ai/k8sgpt/issues/576)) ([c364074](https://github.com/k8sgpt-ai/k8sgpt/commit/c3640744c5cbf036321a14b90c1fdefa17c5321d))
* **deps:** update module github.com/aws/aws-sdk-go to v1.44.304 ([#558](https://github.com/k8sgpt-ai/k8sgpt/issues/558)) ([cf9069e](https://github.com/k8sgpt-ai/k8sgpt/commit/cf9069ef572fea9a947d7de5b0c0e44f34620a69))
* **deps:** update module github.com/aws/aws-sdk-go to v1.44.307 ([#574](https://github.com/k8sgpt-ai/k8sgpt/issues/574)) ([8ae91ec](https://github.com/k8sgpt-ai/k8sgpt/commit/8ae91ec744d1fead3b0aa570c904e9e3ad5ab5ef))
* **deps:** update module github.com/aws/aws-sdk-go to v1.44.308 ([#579](https://github.com/k8sgpt-ai/k8sgpt/issues/579)) ([7e8668a](https://github.com/k8sgpt-ai/k8sgpt/commit/7e8668a56bb25b7da3957cf4c05847d022825c10))
* **deps:** update module github.com/aws/aws-sdk-go to v1.44.309 ([#584](https://github.com/k8sgpt-ai/k8sgpt/issues/584)) ([227e1cd](https://github.com/k8sgpt-ai/k8sgpt/commit/227e1cd69f38654126750902a89408643bdb30fb))
* **deps:** update module github.com/aws/aws-sdk-go to v1.44.312 ([#586](https://github.com/k8sgpt-ai/k8sgpt/issues/586)) ([aafac93](https://github.com/k8sgpt-ai/k8sgpt/commit/aafac9345fbab16b1fe23ea76d6c1c362c44c080))
* **deps:** update module github.com/aws/aws-sdk-go to v1.44.313 ([#587](https://github.com/k8sgpt-ai/k8sgpt/issues/587)) ([f1479ba](https://github.com/k8sgpt-ai/k8sgpt/commit/f1479babbaaf6770d4a106d80f22b2ffb736cbad))
* **deps:** update module github.com/aws/aws-sdk-go to v1.44.315 ([#588](https://github.com/k8sgpt-ai/k8sgpt/issues/588)) ([fe29361](https://github.com/k8sgpt-ai/k8sgpt/commit/fe29361e335f3d186dc3d7651823e9bb03649652))
* **deps:** update module github.com/aws/aws-sdk-go to v1.44.317 ([#591](https://github.com/k8sgpt-ai/k8sgpt/issues/591)) ([9802e82](https://github.com/k8sgpt-ai/k8sgpt/commit/9802e82ff54bc55b670e25f75c69a29a985c21ae))
* **deps:** update module github.com/aws/aws-sdk-go to v1.44.327 ([#597](https://github.com/k8sgpt-ai/k8sgpt/issues/597)) ([aee83b7](https://github.com/k8sgpt-ai/k8sgpt/commit/aee83b74b20117f136876ec426318914aee8c4d1))
* **deps:** update module github.com/aws/aws-sdk-go to v1.44.329 ([#610](https://github.com/k8sgpt-ai/k8sgpt/issues/610)) ([0e5be89](https://github.com/k8sgpt-ai/k8sgpt/commit/0e5be89e5ccb70e9e9a44ad70f161c7b344d04f2))
* **deps:** update module github.com/mittwald/go-helm-client to v0.12.3 ([#582](https://github.com/k8sgpt-ai/k8sgpt/issues/582)) ([c2770f3](https://github.com/k8sgpt-ai/k8sgpt/commit/c2770f38a6f0d3248747927155505db505f5e960))
* **deps:** update module github.com/sashabaranov/go-openai to v1.14.1 ([#573](https://github.com/k8sgpt-ai/k8sgpt/issues/573)) ([b52424a](https://github.com/k8sgpt-ai/k8sgpt/commit/b52424a9b1a554739cb8e08e296045c181d4041c))
* **deps:** update module github.com/sashabaranov/go-openai to v1.14.2 ([#603](https://github.com/k8sgpt-ai/k8sgpt/issues/603)) ([81fcf8b](https://github.com/k8sgpt-ai/k8sgpt/commit/81fcf8b5d46387eca7128b877c0652fdf4ed999c))
* **deps:** update module go.uber.org/zap to v1.25.0 ([#589](https://github.com/k8sgpt-ai/k8sgpt/issues/589)) ([9672cea](https://github.com/k8sgpt-ai/k8sgpt/commit/9672cea228de976772f453e6a05ce05456741de8))
* **deps:** update module golang.org/x/term to v0.11.0 ([#593](https://github.com/k8sgpt-ai/k8sgpt/issues/593)) ([7f109cd](https://github.com/k8sgpt-ai/k8sgpt/commit/7f109cdcfac00a329a53121287e44c2567af6b4a))
* **deps:** update module google.golang.org/grpc to v1.57.0 ([#585](https://github.com/k8sgpt-ai/k8sgpt/issues/585)) ([59897f3](https://github.com/k8sgpt-ai/k8sgpt/commit/59897f330a037f1e5de0f958dd93b826e2ce481d))
* **deps:** update module helm.sh/helm/v3 to v3.12.3 ([#602](https://github.com/k8sgpt-ai/k8sgpt/issues/602)) ([7910c9a](https://github.com/k8sgpt-ai/k8sgpt/commit/7910c9aa2c40f3c1837cce179dd1fc91a9744946))
* optimize analyze service ([#461](https://github.com/k8sgpt-ai/k8sgpt/issues/461)) ([cc665ea](https://github.com/k8sgpt-ai/k8sgpt/commit/cc665ea4f3f279c30c7dd7996786e6bdce88acc8))
* use kubeconfig file when user specify it ([#605](https://github.com/k8sgpt-ai/k8sgpt/issues/605)) ([e3b21ec](https://github.com/k8sgpt-ai/k8sgpt/commit/e3b21ec5ecd5f823470c2c2f570ed89a2c071b5a)), closes [#604](https://github.com/k8sgpt-ai/k8sgpt/issues/604)
### Other
* **deps:** exclude retracted cohere-go versions ([#583](https://github.com/k8sgpt-ai/k8sgpt/issues/583)) ([f8a53a5](https://github.com/k8sgpt-ai/k8sgpt/commit/f8a53a5c035fd3e3598666d9792c4e1231f9838d))
* **deps:** update actions/setup-go digest to 93397be ([#600](https://github.com/k8sgpt-ai/k8sgpt/issues/600)) ([1a0ae1a](https://github.com/k8sgpt-ai/k8sgpt/commit/1a0ae1a086d328b1eaa70c412122427a6e8df2f5))
* **deps:** update google-github-actions/release-please-action digest to ca6063f ([#572](https://github.com/k8sgpt-ai/k8sgpt/issues/572)) ([fba1a8e](https://github.com/k8sgpt-ai/k8sgpt/commit/fba1a8ed8c7cc2f7b0aace246f8797ea6c27e455))
* **deps:** update goreleaser/goreleaser-action digest to 3fa32b8 ([#601](https://github.com/k8sgpt-ai/k8sgpt/issues/601)) ([610720a](https://github.com/k8sgpt-ai/k8sgpt/commit/610720a95c9d5eb49c77e7a929cd766a04e534a4))
* **deps:** update reviewdog/action-golangci-lint digest to 951dc8b ([#594](https://github.com/k8sgpt-ai/k8sgpt/issues/594)) ([9acaec0](https://github.com/k8sgpt-ai/k8sgpt/commit/9acaec00c4d084c4ec3e40e4a6a8b0136dcc4aa1))
* **deps:** update reviewdog/action-golangci-lint digest to f17c2e2 ([#598](https://github.com/k8sgpt-ai/k8sgpt/issues/598)) ([2251321](https://github.com/k8sgpt-ai/k8sgpt/commit/22513216960f06d572ec53480e290b1f4e5ff1d8))
* upgraded cohere backend ([#580](https://github.com/k8sgpt-ai/k8sgpt/issues/580)) ([43b0d70](https://github.com/k8sgpt-ai/k8sgpt/commit/43b0d707e7eac326594f5f6c7ab4c885772846d2))
## [0.3.13](https://github.com/k8sgpt-ai/k8sgpt/compare/v0.3.12...v0.3.13) (2023-07-20)
### Other
* continue on absent service ([#569](https://github.com/k8sgpt-ai/k8sgpt/issues/569)) ([153d38d](https://github.com/k8sgpt-ai/k8sgpt/commit/153d38deb060cb84d606f8391e5700025ce02a9b))
## [0.3.12](https://github.com/k8sgpt-ai/k8sgpt/compare/v0.3.11...v0.3.12) (2023-07-19)
### Features
* add Cohere backend ([#563](https://github.com/k8sgpt-ai/k8sgpt/issues/563)) ([781ecb7](https://github.com/k8sgpt-ai/k8sgpt/commit/781ecb7aad689e6709678c9690c112115e3cf6c7))
### Bug Fixes
* **deps:** update module github.com/aws/aws-sdk-go to v1.44.300 ([#554](https://github.com/k8sgpt-ai/k8sgpt/issues/554)) ([dc46333](https://github.com/k8sgpt-ai/k8sgpt/commit/dc463334bccdf16106cff4e688a83bf0984d6e27))
* **deps:** update module github.com/mittwald/go-helm-client to v0.12.2 ([#562](https://github.com/k8sgpt-ai/k8sgpt/issues/562)) ([2e0db55](https://github.com/k8sgpt-ai/k8sgpt/commit/2e0db553f92b5ca691b5957b180be35131ab4e2f))
* **deps:** update module google.golang.org/grpc to v1.56.2 ([#546](https://github.com/k8sgpt-ai/k8sgpt/issues/546)) ([cc83fe1](https://github.com/k8sgpt-ai/k8sgpt/commit/cc83fe19bafc87647fa0293189f90c84d2dd8edb))
* **deps:** update module helm.sh/helm/v3 to v3.12.2 ([#555](https://github.com/k8sgpt-ai/k8sgpt/issues/555)) ([9eb96c4](https://github.com/k8sgpt-ai/k8sgpt/commit/9eb96c495cdb1247b664de625a036902b5e156ff))
### Other
* fixing edge cases with missing wh service ([#561](https://github.com/k8sgpt-ai/k8sgpt/issues/561)) ([c422215](https://github.com/k8sgpt-ai/k8sgpt/commit/c42221512bfdab7ac792963d459bf9f8dac3954c))
### Docs
* fix readme for anonymization ([#559](https://github.com/k8sgpt-ai/k8sgpt/issues/559)) ([70bec05](https://github.com/k8sgpt-ai/k8sgpt/commit/70bec050d854be6f559065278d6a583d8e0e333b))
## [0.3.11](https://github.com/k8sgpt-ai/k8sgpt/compare/v0.3.10...v0.3.11) (2023-07-14)
### Features
* admission webhooks ([#553](https://github.com/k8sgpt-ai/k8sgpt/issues/553)) ([06e8532](https://github.com/k8sgpt-ai/k8sgpt/commit/06e8532f88616a988a4e41ed8cdac62cf0f243a5))
### Other
* **deps:** update docker/setup-buildx-action digest to 4c0219f ([#547](https://github.com/k8sgpt-ai/k8sgpt/issues/547)) ([1a3f299](https://github.com/k8sgpt-ai/k8sgpt/commit/1a3f2992108e857f8c8c07eff16599d00b50110e))
## [0.3.10](https://github.com/k8sgpt-ai/k8sgpt/compare/v0.3.9...v0.3.10) (2023-07-12)
### Features
* add Validating/Mutating webhook analyzer ([#548](https://github.com/k8sgpt-ai/k8sgpt/issues/548)) ([750a10d](https://github.com/k8sgpt-ai/k8sgpt/commit/750a10d44c59bc90de5241d1128ee74fa38bf350))
### Bug Fixes
* **deps:** update module github.com/aws/aws-sdk-go to v1.44.298 ([#545](https://github.com/k8sgpt-ai/k8sgpt/issues/545)) ([d1096dc](https://github.com/k8sgpt-ai/k8sgpt/commit/d1096dc31a692013f40980649e5cc2d402869ceb))
* **deps:** update module github.com/aws/aws-sdk-go to v1.44.299 ([#549](https://github.com/k8sgpt-ai/k8sgpt/issues/549)) ([ecd7790](https://github.com/k8sgpt-ai/k8sgpt/commit/ecd7790efe2ca88259451761202c90cb842ff04b))
* **deps:** update module github.com/sashabaranov/go-openai to v1.13.0 ([#399](https://github.com/k8sgpt-ai/k8sgpt/issues/399)) ([21df094](https://github.com/k8sgpt-ai/k8sgpt/commit/21df094bda31a14235fb2244e8cef74d3c92d919))
* **deps:** update module github.com/sashabaranov/go-openai to v1.14.0 ([#550](https://github.com/k8sgpt-ai/k8sgpt/issues/550)) ([9dcab94](https://github.com/k8sgpt-ai/k8sgpt/commit/9dcab945460e5972f895fa5302e3425750d635c7))
* **deps:** update module golang.org/x/term to v0.10.0 ([#542](https://github.com/k8sgpt-ai/k8sgpt/issues/542)) ([1276b3e](https://github.com/k8sgpt-ai/k8sgpt/commit/1276b3e89715b1cfb553e60d4f25592acef80a6f))
## [0.3.9](https://github.com/k8sgpt-ai/k8sgpt/compare/v0.3.8...v0.3.9) (2023-07-04)
### Features
* details flag to list command ([#537](https://github.com/k8sgpt-ai/k8sgpt/issues/537)) ([2309b0d](https://github.com/k8sgpt-ai/k8sgpt/commit/2309b0dfe20e27b6afe283a6be21ad7a0652ac99))
* upgrading azure client impl ([#526](https://github.com/k8sgpt-ai/k8sgpt/issues/526)) ([367fe8f](https://github.com/k8sgpt-ai/k8sgpt/commit/367fe8f74c6a9e26f0d9c3b25a86093530fb85b2))
* upgrading the proto files to fix user issues ([#515](https://github.com/k8sgpt-ai/k8sgpt/issues/515)) ([c88fc88](https://github.com/k8sgpt-ai/k8sgpt/commit/c88fc889e4f6089e48f37d90e349d5c61ea0b952))
### Bug Fixes
* 'intergration' typos ([#508](https://github.com/k8sgpt-ai/k8sgpt/issues/508)) ([64b93c9](https://github.com/k8sgpt-ai/k8sgpt/commit/64b93c9116b6a7f82419f1c4fff98fa68b8c0aca))
* add --no-install for activate command ([#536](https://github.com/k8sgpt-ai/k8sgpt/issues/536)) ([1f5462c](https://github.com/k8sgpt-ai/k8sgpt/commit/1f5462c80bd04f63c2b55889c987634251635812))
* **deps:** update module buf.build/gen/go/k8sgpt-ai/k8sgpt/grpc/go to v1.3.0-20230620082254-6f80f9533908.1 ([#516](https://github.com/k8sgpt-ai/k8sgpt/issues/516)) ([06e50d5](https://github.com/k8sgpt-ai/k8sgpt/commit/06e50d57db3aa2e5a68b093e2ba25c0e33dc6343))
* **deps:** update module github.com/aws/aws-sdk-go to v1.44.284 ([#501](https://github.com/k8sgpt-ai/k8sgpt/issues/501)) ([d87127a](https://github.com/k8sgpt-ai/k8sgpt/commit/d87127a309734847a56bf95c2e947e2270f94a88))
* **deps:** update module github.com/aws/aws-sdk-go to v1.44.286 ([#514](https://github.com/k8sgpt-ai/k8sgpt/issues/514)) ([b9cf522](https://github.com/k8sgpt-ai/k8sgpt/commit/b9cf5226853619655e98f2156bfd0b8513511bb3))
* **deps:** update module github.com/aws/aws-sdk-go to v1.44.288 ([#519](https://github.com/k8sgpt-ai/k8sgpt/issues/519)) ([57695b4](https://github.com/k8sgpt-ai/k8sgpt/commit/57695b44b6429319860a76e4e02016dafe3ed0b0))
* **deps:** update module github.com/aws/aws-sdk-go to v1.44.289 ([#524](https://github.com/k8sgpt-ai/k8sgpt/issues/524)) ([fafb695](https://github.com/k8sgpt-ai/k8sgpt/commit/fafb69544f4edda670bad6973332a20a7f0f055e))
* **deps:** update module github.com/aws/aws-sdk-go to v1.44.292 ([#530](https://github.com/k8sgpt-ai/k8sgpt/issues/530)) ([566f752](https://github.com/k8sgpt-ai/k8sgpt/commit/566f7525eef9f65dd2ab6a47bd0012bfb91e2a12))
* **deps:** update module github.com/aws/aws-sdk-go to v1.44.294 ([#535](https://github.com/k8sgpt-ai/k8sgpt/issues/535)) ([3067fa9](https://github.com/k8sgpt-ai/k8sgpt/commit/3067fa98f4a8990c9a930e53ad93f89cf35e0d62))
* **deps:** update module github.com/aws/aws-sdk-go to v1.44.295 ([#540](https://github.com/k8sgpt-ai/k8sgpt/issues/540)) ([767e4cb](https://github.com/k8sgpt-ai/k8sgpt/commit/767e4cbc4127e2017a3a9c4b182ccc833debc6a5))
* **deps:** update module github.com/prometheus/client_golang to v1.16.0 ([#507](https://github.com/k8sgpt-ai/k8sgpt/issues/507)) ([14e5691](https://github.com/k8sgpt-ai/k8sgpt/commit/14e5691190bf772c05477cbcb811ed71bec450a3))
* **deps:** update module google.golang.org/grpc to v1.56.0 ([#510](https://github.com/k8sgpt-ai/k8sgpt/issues/510)) ([f3e0b9b](https://github.com/k8sgpt-ai/k8sgpt/commit/f3e0b9b56d13397c79f57e76bdd6b741bb565fb4))
* **deps:** update module google.golang.org/grpc to v1.56.1 ([#520](https://github.com/k8sgpt-ai/k8sgpt/issues/520)) ([be52308](https://github.com/k8sgpt-ai/k8sgpt/commit/be52308c99f6aed73e2c20d260823795d45876f5))
* **deps:** update module helm.sh/helm/v3 to v3.12.1 ([#503](https://github.com/k8sgpt-ai/k8sgpt/issues/503)) ([0f03ddc](https://github.com/k8sgpt-ai/k8sgpt/commit/0f03ddcf0f5ec79bc6dbb74c654e0d8fac634a0a))
* displaying correct yaml config location on app start ([#521](https://github.com/k8sgpt-ai/k8sgpt/issues/521)) ([b7d4602](https://github.com/k8sgpt-ai/k8sgpt/commit/b7d4602cb8aaaa0c22a0a5941d8c6edad7c58db4))
* remove provider from default on delete ([#529](https://github.com/k8sgpt-ai/k8sgpt/issues/529)) ([5a983c4](https://github.com/k8sgpt-ai/k8sgpt/commit/5a983c4a0a511389e25cffe12999b903b85cd96d))
* typo in add command ([#539](https://github.com/k8sgpt-ai/k8sgpt/issues/539)) ([da750df](https://github.com/k8sgpt-ai/k8sgpt/commit/da750df16bde878f7619aa58ef5e7ef7d3173b2b))
### Other
* **deps:** update anchore/sbom-action action to v0.14.3 ([#517](https://github.com/k8sgpt-ai/k8sgpt/issues/517)) ([0521060](https://github.com/k8sgpt-ai/k8sgpt/commit/05210604109a6e892bb465df11038b8c24d68076))
* **deps:** update docker/build-push-action digest to 2eb1c19 ([#499](https://github.com/k8sgpt-ai/k8sgpt/issues/499)) ([9df75cc](https://github.com/k8sgpt-ai/k8sgpt/commit/9df75cc959f7ed23cae8e3761498ea6c56885788))
* **deps:** update docker/login-action digest to 465a078 ([#488](https://github.com/k8sgpt-ai/k8sgpt/issues/488)) ([c15a561](https://github.com/k8sgpt-ai/k8sgpt/commit/c15a561b635dc678bb8de15c6623914942475537))
* **deps:** update docker/setup-buildx-action digest to 16c0bc4 ([#532](https://github.com/k8sgpt-ai/k8sgpt/issues/532)) ([5662d59](https://github.com/k8sgpt-ai/k8sgpt/commit/5662d5932ff3beb8c1a31fc2088c5e703e90ec79))
* **deps:** update docker/setup-buildx-action digest to ecf9528 ([#498](https://github.com/k8sgpt-ai/k8sgpt/issues/498)) ([f4d7876](https://github.com/k8sgpt-ai/k8sgpt/commit/f4d78768388774f62d87acd89e71689535e538f7))
* **deps:** update google-github-actions/release-please-action digest to 8016a66 ([#523](https://github.com/k8sgpt-ai/k8sgpt/issues/523)) ([d56861d](https://github.com/k8sgpt-ai/k8sgpt/commit/d56861d4bad475da09992813fc256a0d99399eab))
* **deps:** update reviewdog/action-golangci-lint digest to 22adb9d ([#525](https://github.com/k8sgpt-ai/k8sgpt/issues/525)) ([3146754](https://github.com/k8sgpt-ai/k8sgpt/commit/314675477917063dcfb847880fb3186f8bdf32f6))
* **deps:** update reviewdog/action-golangci-lint digest to 994abff ([#513](https://github.com/k8sgpt-ai/k8sgpt/issues/513)) ([1819c3b](https://github.com/k8sgpt-ai/k8sgpt/commit/1819c3bf1512291cd637c115e8b82c9e0e8885a0))
* sorting out the dependency hell ([#518](https://github.com/k8sgpt-ai/k8sgpt/issues/518)) ([cd7807a](https://github.com/k8sgpt-ai/k8sgpt/commit/cd7807a48481f298422d9b1c8066b431fad3ae5a))
## [0.3.8](https://github.com/k8sgpt-ai/k8sgpt/compare/v0.3.7...v0.3.8) (2023-06-15)
### Features
* fix for s3 cache from operator ([f6db6ce](https://github.com/k8sgpt-ai/k8sgpt/commit/f6db6ce86163dcb4b5ec4bd99b8a3842dd0c60bb))
### Bug Fixes
* **deps:** update kubernetes packages to v0.27.3 ([#504](https://github.com/k8sgpt-ai/k8sgpt/issues/504)) ([b1c6ec3](https://github.com/k8sgpt-ai/k8sgpt/commit/b1c6ec3c0919649bc551ec0047a1d9c2420f4264))
## [0.3.7](https://github.com/k8sgpt-ai/k8sgpt/compare/v0.3.6...v0.3.7) (2023-06-13)

View File

@@ -30,7 +30,7 @@ We're happy that you want to contribute to this project. Please read the section
- Assign yourself to the issue, if you are working on it (if you are not a member of the organization, please leave a comment on the issue)
- Make your changes
- Keep pull requests small and focused, if you have multiple changes, please open multiple PRs
- Create a pull request back to the upstream repository and follow the [pull request template](.github/pull_request_template.md) guidelines.
- Create a pull request back to the upstream repository and follow follow the [pull request template](.github/pull_request_template.md) guidelines.
- Wait for a review and address any comments
**Opening PRs**

217
README.md
View File

@@ -14,8 +14,6 @@
It has SRE experience codified into its analyzers and helps to pull out the most relevant information to enrich it with AI.
_Out of the box integration with OpenAI, Azure, Cohere, Amazon Bedrock and local models._
<a href="https://www.producthunt.com/posts/k8sgpt?utm_source=badge-featured&utm_medium=badge&utm_souce=badge-k8sgpt" target="_blank"><img src="https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=389489&theme=light" alt="K8sGPT - K8sGPT&#0032;gives&#0032;Kubernetes&#0032;Superpowers&#0032;to&#0032;everyone | Product Hunt" style="width: 250px; height: 54px;" width="250" height="54" /></a>
<img src="images/demo4.gif" width=650px; />
@@ -36,7 +34,7 @@ brew install k8sgpt
**32 bit:**
<!---x-release-please-start-version-->
```
curl -LO https://github.com/k8sgpt-ai/k8sgpt/releases/download/v0.3.20/k8sgpt_386.rpm
curl -LO https://github.com/k8sgpt-ai/k8sgpt/releases/download/v0.3.7/k8sgpt_386.rpm
sudo rpm -ivh k8sgpt_386.rpm
```
<!---x-release-please-end-->
@@ -45,7 +43,7 @@ brew install k8sgpt
<!---x-release-please-start-version-->
```
curl -LO https://github.com/k8sgpt-ai/k8sgpt/releases/download/v0.3.20/k8sgpt_amd64.rpm
curl -LO https://github.com/k8sgpt-ai/k8sgpt/releases/download/v0.3.7/k8sgpt_amd64.rpm
sudo rpm -ivh -i k8sgpt_amd64.rpm
```
<!---x-release-please-end-->
@@ -57,7 +55,7 @@ brew install k8sgpt
**32 bit:**
<!---x-release-please-start-version-->
```
curl -LO https://github.com/k8sgpt-ai/k8sgpt/releases/download/v0.3.20/k8sgpt_386.deb
curl -LO https://github.com/k8sgpt-ai/k8sgpt/releases/download/v0.3.7/k8sgpt_386.deb
sudo dpkg -i k8sgpt_386.deb
```
<!---x-release-please-end-->
@@ -65,7 +63,7 @@ brew install k8sgpt
<!---x-release-please-start-version-->
```
curl -LO https://github.com/k8sgpt-ai/k8sgpt/releases/download/v0.3.20/k8sgpt_amd64.deb
curl -LO https://github.com/k8sgpt-ai/k8sgpt/releases/download/v0.3.7/k8sgpt_amd64.deb
sudo dpkg -i k8sgpt_amd64.deb
```
<!---x-release-please-end-->
@@ -78,14 +76,14 @@ brew install k8sgpt
**32 bit:**
<!---x-release-please-start-version-->
```
curl -LO https://github.com/k8sgpt-ai/k8sgpt/releases/download/v0.3.20/k8sgpt_386.apk
curl -LO https://github.com/k8sgpt-ai/k8sgpt/releases/download/v0.3.7/k8sgpt_386.apk
apk add k8sgpt_386.apk
```
<!---x-release-please-end-->
**64 bit:**
<!---x-release-please-start-version-->
```
curl -LO https://github.com/k8sgpt-ai/k8sgpt/releases/download/v0.3.20/k8sgpt_amd64.apk
curl -LO https://github.com/k8sgpt-ai/k8sgpt/releases/download/v0.3.7/k8sgpt_amd64.apk
apk add k8sgpt_amd64.apk
```
<!---x-release-please-end-->x
@@ -130,7 +128,7 @@ _This mode of operation is ideal for continuous monitoring of your cluster and c
* 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.
* You also run `k8sgpt analyze --with-doc` (with or without the explain flag) to get the official documentation from kubernetes.
* You also run `k8sgpt analyze --with-doc` (with or without the explain flag) to get the official documention from kubernetes.
## Analyzers
@@ -151,8 +149,6 @@ you will be able to write your own analyzers.
- [x] deploymentAnalyzer
- [x] cronJobAnalyzer
- [x] nodeAnalyzer
- [x] mutatingWebhookAnalyzer
- [x] validatingWebhookAnalyzer
#### Optional
@@ -306,7 +302,7 @@ To start the API server, follow the instruction in [LocalAI](https://github.com/
To run k8sgpt, run `k8sgpt auth add` with the `localai` backend:
```
k8sgpt auth add --backend localai --model <model_name> --baseurl http://localhost:8080/v1 --temperature 0.7
k8sgpt auth add --backend localai --model <model_name> --baseurl http://localhost:8080/v1
```
Now you can analyze with the `localai` backend:
@@ -338,124 +334,6 @@ k8sgpt analyze --explain --backend azureopenai
</details>
<details>
<summary>Cohere provider</summary>
<em>Prerequisites:</em> a Cohere API key is needed, please visit the [Cohere dashboard](https://dashboard.cohere.ai/api-keys) to create one.
To run k8sgpt, run `k8sgpt auth` with the `cohere` backend:
```
k8sgpt auth add --backend cohere --model command-nightly
```
Lastly, enter your Cohere API key, after the prompt.
Now you are ready to analyze with the Cohere backend:
```
k8sgpt analyze --explain --backend cohere
```
</details>
<details>
<summary>Amazon Bedrock provider</summary>
<em>Prerequisites</em>
Bedrock API access is needed.
<img src="images/bedrock.png" width="500px;" />
As illustrated below, you will need to enable this in the [AWS Console](https://eu-central-1.console.aws.amazon.com/bedrock/home?region=eu-central-1#/modelaccess)
In addition to this you will need to set the follow local environmental variables:
```
- AWS_ACCESS_KEY
- AWS_SECRET_ACCESS_KEY
- AWS_DEFAULT_REGION
```
```
k8sgpt auth add --backend amazonbedrock --model anthropic.claude-v2
```
#### Usage
```
k8sgpt analyze -e -b amazonbedrock
0 argocd/argocd-application-controller(argocd-application-controller)
- Error: StatefulSet uses the service argocd/argocd-application-controller which does not exist.
You're right, I don't have enough context to determine if a StatefulSet is correctly configured to use a non-existent service. A StatefulSet manages Pods with persistent storage, and the Pods are created from the same spec. The service name referenced in the StatefulSet configuration would need to match an existing Kubernetes service for the Pods to connect to. Without more details on the specific StatefulSet and environment, I can't confirm whether the configuration is valid or not.
```
</details>
<details>
<summary>Amazon SageMaker Provider</summary>
#### Prerequisites
1. **AWS CLI Configuration**: Make sure you have the AWS Command Line Interface (CLI) configured on your machine. If you haven't already configured the AWS CLI, you can follow the official AWS documentation for instructions on how to do it: [AWS CLI Configuration Guide](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html).
2. **SageMaker Instance**: You need to have an Amazon SageMaker instance set up. If you don't have one already, you can follow the step-by-step instructions provided in this repository for creating a SageMaker instance: [llm-sagemaker-jumpstart-cdk](https://github.com/zaremb/llm-sagemaker-jumpstart-cdk).
#### Backend Configuration
To add amazonsagemaker backend two parameters are required:
* `--endpointname` Amazon SageMaker endpoint name.
* `--providerRegion` AWS region where SageMaker instance is created. `k8sgpt` uses this region to connect to SageMaker (not the one defined with AWS CLI or environment variables )
To add amazonsagemaker as a backend run:
```bash
k8sgpt auth add --backend amazonsagemaker --providerRegion eu-west-1 --endpointname endpoint-xxxxxxxxxx
```
#### Optional params
Optionally, when adding the backend and later by changing the configuration file, you can set the following parameters:
`-l, --maxtokens int` Specify a maximum output length. Adjust (1-...) to control text length. Higher values produce longer output, lower values limit length (default 2048)
`-t, --temperature float32` The sampling temperature, value ranges between 0 ( output be more deterministic) and 1 (more random) (default 0.7)
`-c, --topp float32` Probability Cutoff: Set a threshold (0.0-1.0) to limit word choices. Higher values add randomness, lower values increase predictability. (default 0.5)
To make amazonsagemaker as a default backend run:
```bash
k8sgpt auth default -p amazonsagemaker
```
#### AmazonSageMaker Usage
```bash
./k8sgpt analyze -e -b amazonsagemaker
100% |███████████████████████████████████████████████████████████████████████████████████████████████████████████████████| (1/1, 14 it/min)
AI Provider: amazonsagemaker
0 default/nginx(nginx)
- Error: Back-off pulling image "nginxx"
Error: Back-off pulling image "nginxx"
Solution:
1. Check if the image exists in the registry by running `docker image ls nginxx`.
2. If the image is not found, try pulling it by running `docker pull nginxx`.
3. If the image is still not available, check if there are any network issues by running `docker network inspect` and `docker network list`.
4. If the issue persists, try restarting the Docker daemon by running `sudo service docker restart`.
```
</details>
<details>
@@ -475,8 +353,6 @@ Active:
Unused:
> localai
> noopai
> amazonbedrock
> cohere
```
@@ -498,7 +374,6 @@ With this option, the data is anonymized before being sent to the AI Backend. Du
<summary> Anonymization </summary>
1. Error reported during analysis:
```bash
Error: HorizontalPodAutoscaler uses StatefulSet/fake-deployment as ScaleTargetRef which does not exist.
@@ -519,61 +394,12 @@ The Kubernetes system is trying to scale a StatefulSet named tGLcCRcHa1Ce5Rs usi
The Kubernetes system is trying to scale a StatefulSet named fake-deployment using the HorizontalPodAutoscaler, but it cannot find the StatefulSet. The solution is to verify that the StatefulSet name is spelled correctly and exists in the same namespace as the HorizontalPodAutoscaler.
```
Note: **Anonymization does not currently apply to events.**
### Further Details
**Anonymization does not currently apply to events.**
*In a few analysers like Pod, we feed to the AI backend the event messages which are not known beforehand thus we are not masking them for the **time being**.*
- The following is the list of analysers in which data is **being masked**:-
- Statefulset
- Service
- PodDisruptionBudget
- Node
- NetworkPolicy
- Ingress
- HPA
- Deployment
- Cronjob
- The following is the list of analysers in which data is **not being masked**:-
- RepicaSet
- PersistentVolumeClaim
- Pod
- **_*Events_**
***Note**:
- k8gpt will not mask the above analysers because they do not send any identifying information except **Events** analyser.
- Masking for **Events** analyzer is scheduled in the near future as seen in this [issue](https://github.com/k8sgpt-ai/k8sgpt/issues/560). _Further research has to be made to understand the patterns and be able to mask the sensitive parts of an event like pod name, namespace etc._
- The following is the list of fields which are not **being masked**:-
- Describe
- ObjectStatus
- Replicas
- ContainerStatus
- **_*Event Message_**
- ReplicaStatus
- Count (Pod)
***Note**:
- It is quite possible the payload of the event message might have something like "super-secret-project-pod-X crashed" which we don't currently redact _(scheduled in the near future as seen in this [issue](https://github.com/k8sgpt-ai/k8sgpt/issues/560))_.
### Proceed with care
- The K8gpt team recommends using an entirely different backend **(a local model) in critical production environments**. By using a local model, you can rest assured that everything stays within your DMZ, and nothing is leaked.
- If there is any uncertainty about the possibility of sending data to a public LLM (open AI, Azure AI) and it poses a risk to business-critical operations, then, in such cases, the use of public LLM should be avoided based on personal assessment and the jurisdiction of risks involved.
</details>
<details>
<summary> Configuration management</summary>
`k8sgpt` stores config data in the `$XDG_CONFIG_HOME/k8sgpt/k8sgpt.yaml` file. The data is stored in plain text, including your OpenAI key.
Config file locations:
@@ -585,23 +411,18 @@ Config file locations:
</details>
<details>
There may be scenarios where caching remotely is preferred.
In these scenarios K8sGPT supports AWS S3 or Azure Blob storage Integration.
There may be scenarios where caching remotely is prefered.
In these scenarios K8sGPT supports AWS S3 Integration.
<summary> Remote caching </summary>
<em>Note: You can only configure and use only one remote cache at a time</em>
<summary> Remote caching </summary>
_As a prerequisite `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` are required as environmental variables._
_Adding a remote cache_
* AWS S3
* _As a prerequisite `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` are required as environmental variables._
* Configuration, ``` k8sgpt cache add --region <aws region> --bucket <name> ```
* K8sGPT will create the bucket if it does not exist
* Azure Storage
* We support a number of [techniques](https://learn.microsoft.com/en-us/azure/developer/go/azure-sdk-authentication?tabs=bash#2-authenticate-with-azure) to authenticate against Azure
* Configuration, ``` k8sgpt cache add --storageacc <storage account name> --container <container name> ```
* K8sGPT assumes that the storage account already exist and it will create the container if it does not exist
* It's **users'** responsibility have to grant specific permissions to their identity in order to be able to upload blob files and create SA containers (e.g Storage Blob Data Contributor)
Note: this will create the bucket if it does not exist
```
k8sgpt cache add --region <aws region> --bucket <name>
```
_Listing cache items_
```
@@ -609,9 +430,9 @@ k8sgpt cache list
```
_Removing the remote cache_
Note: this will not delete the upstream S3 bucket or Azure storage container
Note: this will not delete the bucket
```
k8sgpt cache remove
k8sgpt cache remove --bucket <name>
```
</details>

View File

@@ -8,4 +8,4 @@ For example if there is a vulnerability in release `0.1.0` we will fix that rele
## Reporting a Vulnerability
If you are aware of a vulnerability please feel free to disclose it responsibly to contact@k8sgpt.ai or to one of our maintainers in our Slack community.
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

@@ -26,25 +26,16 @@ import (
"golang.org/x/term"
)
const (
defaultBackend = "openai"
defaultModel = "gpt-3.5-turbo"
)
var addCmd = &cobra.Command{
Use: "add",
Short: "Add new provider",
Long: "The add command allows to configure a new backend AI provider",
Short: "Configure new provider",
Long: "The new command allows to configure a new backend AI provider",
PreRun: func(cmd *cobra.Command, args []string) {
backend, _ := cmd.Flags().GetString("backend")
if strings.ToLower(backend) == "azureopenai" {
_ = cmd.MarkFlagRequired("engine")
_ = cmd.MarkFlagRequired("baseurl")
}
if strings.ToLower(backend) == "amazonsagemaker" {
_ = cmd.MarkFlagRequired("endpointname")
_ = cmd.MarkFlagRequired("providerRegion")
}
},
Run: func(cmd *cobra.Command, args []string) {
@@ -74,27 +65,14 @@ var addCmd = &cobra.Command{
}
// check if backend is not empty and a valid value
if backend == "" {
color.Yellow(fmt.Sprintf("Warning: backend input is empty, will use the default value: %s", defaultBackend))
backend = defaultBackend
} else {
if !validBackend(ai.Backends, backend) {
color.Red("Error: Backend AI accepted values are '%v'", strings.Join(ai.Backends, ", "))
os.Exit(1)
}
if backend == "" || !validBackend(ai.Backends, backend) {
color.Red("Error: Backend AI cannot be empty and accepted values are '%v'", strings.Join(ai.Backends, ", "))
os.Exit(1)
}
// check if model is not empty
if model == "" {
model = defaultModel
color.Yellow(fmt.Sprintf("Warning: model input is empty, will use the default value: %s", defaultModel))
}
if temperature > 1.0 || temperature < 0.0 {
color.Red("Error: temperature ranges from 0 to 1.")
os.Exit(1)
}
if topP > 1.0 || topP < 0.0 {
color.Red("Error: topP ranges from 0 to 1.")
color.Red("Error: Model cannot be empty.")
os.Exit(1)
}
@@ -111,16 +89,11 @@ var addCmd = &cobra.Command{
// create new provider object
newProvider := ai.AIProvider{
Name: backend,
Model: model,
Password: password,
BaseURL: baseURL,
EndpointName: endpointName,
Engine: engine,
Temperature: temperature,
ProviderRegion: providerRegion,
TopP: topP,
MaxTokens: maxTokens,
Name: backend,
Model: model,
Password: password,
BaseURL: baseURL,
Engine: engine,
}
if providerIndex == -1 {
@@ -141,23 +114,13 @@ var addCmd = &cobra.Command{
func init() {
// add flag for backend
addCmd.Flags().StringVarP(&backend, "backend", "b", defaultBackend, "Backend AI provider")
addCmd.Flags().StringVarP(&backend, "backend", "b", "openai", "Backend AI provider")
// add flag for model
addCmd.Flags().StringVarP(&model, "model", "m", defaultModel, "Backend AI model")
addCmd.Flags().StringVarP(&model, "model", "m", "gpt-3.5-turbo", "Backend AI model")
// add flag for password
addCmd.Flags().StringVarP(&password, "password", "p", "", "Backend AI password")
// add flag for url
addCmd.Flags().StringVarP(&baseURL, "baseurl", "u", "", "URL AI provider, (e.g `http://localhost:8080/v1`)")
// add flag for endpointName
addCmd.Flags().StringVarP(&endpointName, "endpointname", "n", "", "Endpoint Name, (e.g `endpoint-xxxxxxxxxxxx`)")
// add flag for topP
addCmd.Flags().Float32VarP(&topP, "topp", "c", 0.5, "Probability Cutoff: Set a threshold (0.0-1.0) to limit word choices. Higher values add randomness, lower values increase predictability.")
// max tokens
addCmd.Flags().IntVarP(&maxTokens, "maxtokens", "l", 2048, "Specify a maximum output length. Adjust (1-...) to control text length. Higher values produce longer output, lower values limit length")
// add flag for temperature
addCmd.Flags().Float32VarP(&temperature, "temperature", "t", 0.7, "The sampling temperature, value ranges between 0 ( output be more deterministic) and 1 (more random)")
// add flag for azure open ai engine/deployment name
addCmd.Flags().StringVarP(&engine, "engine", "e", "", "Azure AI deployment name")
//add flag for amazonbedrock region name
addCmd.Flags().StringVarP(&providerRegion, "providerRegion", "r", "", "Provider Region name")
}

View File

@@ -19,16 +19,11 @@ import (
)
var (
backend string
password string
baseURL string
endpointName string
model string
engine string
temperature float32
providerRegion string
topP float32
maxTokens int
backend string
password string
baseURL string
model string
engine string
)
var configAI ai.AIConfiguration

View File

@@ -23,9 +23,6 @@ import (
"github.com/spf13/viper"
)
var details bool
var userInput string
var listCmd = &cobra.Command{
Use: "list",
Short: "List configured providers",
@@ -39,11 +36,6 @@ var listCmd = &cobra.Command{
os.Exit(1)
}
if details {
fmt.Println("Show password ? (y/n)")
fmt.Scan(&userInput)
}
// Print the default if it is set
fmt.Print(color.YellowString("Default: \n"))
if configAI.DefaultProvider != "" {
@@ -63,13 +55,6 @@ var listCmd = &cobra.Command{
}
if providerExists {
fmt.Printf("> %s\n", color.GreenString(aiBackend))
if details {
for _, provider := range configAI.Providers {
if provider.Name == aiBackend {
printDetails(provider, userInput)
}
}
}
}
}
fmt.Print(color.YellowString("Unused: \n"))
@@ -86,19 +71,3 @@ var listCmd = &cobra.Command{
}
},
}
func init() {
listCmd.Flags().BoolVar(&details, "details", false, "Print active provider configuration details")
}
func printDetails(provider ai.AIProvider, userInput string) {
if provider.Model != "" {
fmt.Printf(" - Model: %s\n", provider.Model)
}
if provider.Engine != "" {
fmt.Printf(" - Engine: %s\n", provider.Engine)
}
if provider.BaseURL != "" {
fmt.Printf(" - BaseURL: %s\n", provider.BaseURL)
}
}

View File

@@ -46,9 +46,6 @@ var removeCmd = &cobra.Command{
if b == provider.Name {
foundBackend = true
configAI.Providers = append(configAI.Providers[:i], configAI.Providers[i+1:]...)
if configAI.DefaultProvider == b {
configAI.DefaultProvider = "openai"
}
color.Green("%s deleted from the AI backend provider list", b)
break
}

View File

@@ -49,10 +49,6 @@ var updateCmd = &cobra.Command{
color.Red("Error: backend must be set.")
os.Exit(1)
}
if temperature > 1.0 || temperature < 0.0 {
color.Red("Error: temperature ranges from 0 to 1.")
os.Exit(1)
}
for _, b := range inputBackends {
foundBackend := false
@@ -78,7 +74,6 @@ var updateCmd = &cobra.Command{
if engine != "" {
configAI.Providers[i].Engine = engine
}
configAI.Providers[i].Temperature = temperature
color.Green("%s updated in the AI backend provider list", b)
}
}
@@ -106,8 +101,6 @@ func init() {
updateCmd.Flags().StringVarP(&password, "password", "p", "", "Update backend AI password")
// update flag for url
updateCmd.Flags().StringVarP(&baseURL, "baseurl", "u", "", "Update URL AI provider, (e.g `http://localhost:8080/v1`)")
// add flag for temperature
updateCmd.Flags().Float32VarP(&temperature, "temperature", "t", 0.7, "The sampling temperature, value ranges between 0 ( output be more deterministic) and 1 (more random)")
// update flag for azure open ai engine/deployment name
updateCmd.Flags().StringVarP(&engine, "engine", "e", "", "Update Azure AI deployment name")
}

27
cmd/cache/add.go vendored
View File

@@ -24,10 +24,7 @@ import (
)
var (
region string
bucketName string
storageAccount string
containerName string
region string
)
// addCmd represents the add command
@@ -36,12 +33,10 @@ var addCmd = &cobra.Command{
Short: "Add a remote cache",
Long: `This command allows you to add a remote cache to store the results of an analysis.
The supported cache types are:
- Azure Blob storage
- S3`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Println(color.YellowString("Adding remote based cache"))
remoteCache := cache.NewCacheProvider(bucketname, region, storageAccount, containerName)
err := cache.AddRemoteCache(remoteCache)
fmt.Println(color.YellowString("Adding remote S3 based cache"))
err := cache.AddRemoteCache(bucketname, region)
if err != nil {
color.Red("Error: %v", err)
os.Exit(1)
@@ -51,15 +46,9 @@ var addCmd = &cobra.Command{
func init() {
CacheCmd.AddCommand(addCmd)
addCmd.Flags().StringVarP(&region, "region", "r", "", "The region to use for the AWS S3 cache")
addCmd.Flags().StringVarP(&bucketname, "bucket", "b", "", "The name of the AWS S3 bucket to use for the cache")
addCmd.MarkFlagsRequiredTogether("region", "bucket")
addCmd.Flags().StringVarP(&storageAccount, "storageacc", "s", "", "The Azure storage account name of the container")
addCmd.Flags().StringVarP(&containerName, "container", "c", "", "The Azure container name to use for the cache")
addCmd.MarkFlagsRequiredTogether("storageacc", "container")
// Tedious check to ensure we don't include arguments from different providers
addCmd.MarkFlagsMutuallyExclusive("region", "storageacc")
addCmd.MarkFlagsMutuallyExclusive("region", "container")
addCmd.MarkFlagsMutuallyExclusive("bucket", "storageacc")
addCmd.MarkFlagsMutuallyExclusive("bucket", "container")
addCmd.Flags().StringVarP(&region, "region", "r", "", "The region to use for the cache")
addCmd.Flags().StringVarP(&bucketname, "bucket", "b", "", "The name of the bucket to use for the cache")
addCmd.MarkFlagRequired("bucket")
addCmd.MarkFlagRequired("region")
}

2
cmd/cache/list.go vendored
View File

@@ -42,7 +42,7 @@ var listCmd = &cobra.Command{
color.Red("Error: %v", err)
os.Exit(1)
}
for _, name := range names {
println(name)
}

2
cmd/cache/remove.go vendored
View File

@@ -29,7 +29,7 @@ var removeCmd = &cobra.Command{
Long: `This command allows you to remove the remote cache and use the default filecache.`,
Run: func(cmd *cobra.Command, args []string) {
err := cache.RemoveRemoteCache()
err := cache.RemoveRemoteCache(bucketname)
if err != nil {
color.Red("Error: %v", err)
os.Exit(1)

View File

@@ -18,7 +18,6 @@ import (
"github.com/fatih/color"
"github.com/k8sgpt-ai/k8sgpt/pkg/analyzer"
"github.com/k8sgpt-ai/k8sgpt/pkg/integration"
"github.com/k8sgpt-ai/k8sgpt/pkg/util"
"github.com/spf13/cobra"
"github.com/spf13/viper"
@@ -31,7 +30,7 @@ var listCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
activeFilters := viper.GetStringSlice("active_filters")
coreFilters, additionalFilters, integrationFilters := analyzer.ListFilters()
integration := integration.NewIntegration()
availableFilters := append(append(coreFilters, additionalFilters...), integrationFilters...)
if len(activeFilters) == 0 {
@@ -42,16 +41,10 @@ var listCmd = &cobra.Command{
for _, filter := range activeFilters {
// if the filter is an integration, mark this differently
// but if the integration is inactive, remove
if util.SliceContainsString(integrationFilters, filter) {
fmt.Printf("> %s\n", color.BlueString("%s (integration)", filter))
} else {
// This strange bit of logic will loop through every integration via
// OwnsAnalyzer subcommand to check the filter and as the integrationFilters...
// was no match, we know this isn't part of an active integration
if _, err := integration.AnalyzerByIntegration(filter); err != nil {
fmt.Printf("> %s\n", color.GreenString(filter))
}
fmt.Printf("> %s\n", color.GreenString(filter))
}
}

View File

@@ -21,10 +21,6 @@ import (
"github.com/spf13/viper"
)
var (
skipInstall bool
)
// activateCmd represents the activate command
var activateCmd = &cobra.Command{
Use: "activate [integration]",
@@ -43,7 +39,7 @@ var activateCmd = &cobra.Command{
integration := integration.NewIntegration()
// Check if the integation exists
err := integration.Activate(integrationName, namespace, activeFilters, skipInstall)
err := integration.Activate(integrationName, namespace, activeFilters)
if err != nil {
color.Red("Error: %v", err)
return
@@ -55,6 +51,5 @@ var activateCmd = &cobra.Command{
func init() {
IntegrationCmd.AddCommand(activateCmd)
activateCmd.Flags().BoolVarP(&skipInstall, "no-install", "s", false, "Only activate the integration filter without installing the filter (for example, if that filter plugin is already deployed in cluster, we do not need to re-install it again)")
}

View File

@@ -25,8 +25,8 @@ var (
var IntegrationCmd = &cobra.Command{
Use: "integration",
Aliases: []string{"integrations"},
Short: "Integrate another tool into K8sGPT",
Long: `Integrate another tool into K8sGPT. For example:
Short: "Intergrate another tool into K8sGPT",
Long: `Intergrate another tool into K8sGPT. For example:
k8sgpt integration activate trivy

View File

@@ -14,7 +14,6 @@ limitations under the License.
package cmd
import (
"fmt"
"os"
"path/filepath"
@@ -74,7 +73,7 @@ func init() {
rootCmd.AddCommand(integration.IntegrationCmd)
rootCmd.AddCommand(serve.ServeCmd)
rootCmd.AddCommand(cache.CacheCmd)
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", fmt.Sprintf("Default config file (%s/k8sgpt/k8sgpt.yaml)", xdg.ConfigHome))
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", "", "Path to a kubeconfig. Only required if out-of-cluster.")
}

View File

@@ -15,7 +15,6 @@ package serve
import (
"os"
"strconv"
"github.com/fatih/color"
"github.com/k8sgpt-ai/k8sgpt/pkg/ai"
@@ -25,10 +24,6 @@ import (
"go.uber.org/zap"
)
const (
defaultTemperature float32 = 0.7
)
var (
port string
metricsPort string
@@ -49,23 +44,6 @@ var ServeCmd = &cobra.Command{
}
var aiProvider *ai.AIProvider
if len(configAI.Providers) == 0 {
// we validate and set temperature for our backend
temperature := func() float32 {
env := os.Getenv("K8SGPT_TEMPERATURE")
if env == "" {
return defaultTemperature
}
temperature, err := strconv.ParseFloat(env, 32)
if err != nil {
color.Red("Unable to convert Temperature value: %v", err)
os.Exit(1)
}
if temperature > 1.0 || temperature < 0.0 {
color.Red("Error: temperature ranges from 0 to 1.")
os.Exit(1)
}
return float32(temperature)
}
// Check for env injection
backend = os.Getenv("K8SGPT_BACKEND")
password := os.Getenv("K8SGPT_PASSWORD")
@@ -77,12 +55,11 @@ var ServeCmd = &cobra.Command{
envIsSet := backend != "" || password != "" || model != ""
if envIsSet {
aiProvider = &ai.AIProvider{
Name: backend,
Password: password,
Model: model,
BaseURL: baseURL,
Engine: engine,
Temperature: temperature(),
Name: backend,
Password: password,
Model: model,
BaseURL: baseURL,
Engine: engine,
}
configAI.Providers = append(configAI.Providers, *aiProvider)

19
demo Executable file
View File

@@ -0,0 +1,19 @@
#!/bin/bash
########################
# include the magic
########################
. demo-magic.sh
# hide the evidence
clear
pe "./k8sgpt analyze --explain"
pe "./k8sgpt filter list"
pe "./k8sgpt integration list"
pe "./k8sgpt integration activate trivy"
pe "./k8sgpt analyze --filter VulnerabilityReport -o json | jq ."

165
go.mod
View File

@@ -3,79 +3,59 @@ module github.com/k8sgpt-ai/k8sgpt
go 1.20
require (
github.com/aquasecurity/trivy-operator v0.15.1
github.com/aquasecurity/trivy-operator v0.13.2
github.com/fatih/color v1.15.0
github.com/magiconair/properties v1.8.7
github.com/mittwald/go-helm-client v0.12.3
github.com/sashabaranov/go-openai v1.16.0
github.com/mittwald/go-helm-client v0.12.1
github.com/sashabaranov/go-openai v1.9.3
github.com/schollz/progressbar/v3 v3.13.1
github.com/spf13/cobra v1.7.0
github.com/spf13/viper v1.17.0
github.com/spf13/viper v1.16.0
github.com/stretchr/testify v1.8.4
golang.org/x/term v0.13.0
helm.sh/helm/v3 v3.13.1
k8s.io/api v0.28.3
k8s.io/apimachinery v0.28.3
k8s.io/client-go v0.28.3
k8s.io/kubectl v0.28.3
golang.org/x/term v0.9.0
helm.sh/helm/v3 v3.12.0
k8s.io/api v0.27.2
k8s.io/apimachinery v0.27.2
k8s.io/client-go v0.27.2
k8s.io/kubectl v0.27.2
)
require github.com/adrg/xdg v0.4.0
require (
buf.build/gen/go/k8sgpt-ai/k8sgpt/grpc/go v1.3.0-20231002095256-194bc640518b.1
buf.build/gen/go/k8sgpt-ai/k8sgpt/protocolbuffers/go v1.31.0-20231002095256-194bc640518b.1
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.0
github.com/aws/aws-sdk-go v1.47.1
github.com/cohere-ai/cohere-go v0.2.0
buf.build/gen/go/k8sgpt-ai/k8sgpt/grpc/go v1.3.0-20230524215339-41d88e13ab7e.1
buf.build/gen/go/k8sgpt-ai/k8sgpt/protocolbuffers/go v1.30.0-20230524215339-41d88e13ab7e.1
github.com/aws/aws-sdk-go v1.44.281
)
require (
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.8.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1 // indirect
github.com/Microsoft/hcsshim v0.11.0 // indirect
github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092 // indirect
github.com/cohere-ai/tokenizer v1.1.1 // indirect
github.com/dlclark/regexp2 v1.4.0 // indirect
github.com/golang-jwt/jwt/v5 v5.0.0 // indirect
github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
github.com/sagikazarmark/locafero v0.3.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 // indirect
)
require github.com/jmespath/go-jmespath v0.4.0 // indirect
require (
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 // indirect
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
github.com/BurntSushi/toml v1.3.2 // indirect
github.com/BurntSushi/toml v1.2.1 // indirect
github.com/MakeNowJust/heredoc v1.0.0 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.2.1 // indirect
github.com/Masterminds/semver/v3 v3.2.0 // indirect
github.com/Masterminds/sprig/v3 v3.2.3 // indirect
github.com/Masterminds/squirrel v1.5.4 // indirect
github.com/aquasecurity/defsec v0.89.0 // indirect
github.com/aquasecurity/go-dep-parser v0.0.0-20230605080024-b71d9356a6c6 // indirect
github.com/Masterminds/squirrel v1.5.3 // indirect
github.com/aquasecurity/defsec v0.86.0 // indirect
github.com/aquasecurity/go-dep-parser v0.0.0-20230413091456-df0396537e15 // indirect
github.com/aquasecurity/table v1.8.0 // indirect
github.com/aquasecurity/tml v0.6.1 // indirect
github.com/aquasecurity/trivy v0.42.1 // indirect
github.com/aquasecurity/trivy-db v0.0.0-20230515061101-378ab9ed302c // indirect
github.com/aquasecurity/trivy v0.40.0 // indirect
github.com/aquasecurity/trivy-db v0.0.0-20230411140759-3c2ee2168575 // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/chai2010/gettext-go v1.0.2 // indirect
github.com/containerd/containerd v1.7.6 // indirect
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/docker/cli v24.0.6+incompatible // indirect
github.com/containerd/containerd v1.7.0 // indirect
github.com/cyphar/filepath-securejoin v0.2.3 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/docker/cli v23.0.1+incompatible // indirect
github.com/docker/distribution v2.8.2+incompatible // indirect
github.com/docker/docker v24.0.6+incompatible // indirect
github.com/docker/docker v23.0.3+incompatible // indirect
github.com/docker/docker-credential-helpers v0.7.0 // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-metrics v0.0.1 // indirect
@@ -95,12 +75,12 @@ require (
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/btree v1.1.2 // indirect
github.com/google/gnostic v0.7.0
github.com/google/gnostic v0.6.9
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/go-containerregistry v0.15.2 // indirect
github.com/google/go-containerregistry v0.14.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/google/uuid v1.3.1 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/gorilla/mux v1.8.0 // indirect
github.com/gosuri/uitable v0.0.4 // indirect
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
@@ -113,13 +93,13 @@ require (
github.com/jmoiron/sqlx v1.3.5 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.17.0 // indirect
github.com/klauspost/compress v1.16.0 // indirect
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
github.com/lib/pq v1.10.9 // indirect
github.com/lib/pq v1.10.7 // indirect
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/masahiro331/go-xfs-filesystem v0.0.0-20230608043311-a335f4599b70 // indirect
github.com/masahiro331/go-xfs-filesystem v0.0.0-20221225060805-c02764233454 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.18 // indirect
github.com/mattn/go-runewidth v0.0.14 // indirect
@@ -131,74 +111,81 @@ require (
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/moby/locker v1.0.1 // indirect
github.com/moby/spdystream v0.2.0 // indirect
github.com/moby/term v0.5.0 // indirect
github.com/moby/term v0.0.0-20221205130635-1aeaba878587 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.0-rc5 // indirect
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
github.com/opencontainers/image-spec v1.1.0-rc2.0.20221020182949-4df8887994e8 // indirect
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_golang v1.17.0
github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 // indirect
github.com/prometheus/common v0.44.0 // indirect
github.com/prometheus/procfs v0.11.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_golang v1.15.1
github.com/prometheus/client_model v0.3.0 // indirect
github.com/prometheus/common v0.42.0 // indirect
github.com/prometheus/procfs v0.9.0 // indirect
github.com/rivo/uniseg v0.4.4 // indirect
github.com/robfig/cron/v3 v3.0.1
github.com/rubenv/sql-migrate v1.5.2 // indirect
github.com/rubenv/sql-migrate v1.3.1 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/samber/lo v1.38.1 // indirect
github.com/samber/lo v1.37.0 // indirect
github.com/shopspring/decimal v1.3.1 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/sirupsen/logrus v1.9.0 // indirect
github.com/spdx/tools-golang v0.5.0 // indirect
github.com/spf13/afero v1.10.0 // indirect
github.com/spf13/afero v1.9.5 // indirect
github.com/spf13/cast v1.5.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/subosito/gotenv v1.4.2 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
github.com/xlab/treeprint v1.2.0 // indirect
github.com/xlab/treeprint v1.1.0 // indirect
go.opentelemetry.io/otel v1.14.0 // indirect
go.opentelemetry.io/otel/trace v1.14.0 // indirect
go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect
go.starlark.net v0.0.0-20221020143700-22309ac47eac // indirect
go.uber.org/atomic v1.10.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.26.0
golang.org/x/crypto v0.14.0 // indirect
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/oauth2 v0.12.0 // indirect
golang.org/x/sync v0.3.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect
go.uber.org/zap v1.24.0
golang.org/x/crypto v0.9.0 // indirect
golang.org/x/exp v0.0.0-20230124195608-d38c7dcee874 // indirect
golang.org/x/net v0.10.0 // indirect
golang.org/x/oauth2 v0.7.0 // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/sys v0.9.0 // indirect
golang.org/x/text v0.9.0 // indirect
golang.org/x/time v0.3.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/grpc v1.59.0
google.golang.org/protobuf v1.31.0 // indirect
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
google.golang.org/grpc v1.55.0
google.golang.org/protobuf v1.30.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/apiextensions-apiserver v0.28.2 // indirect
k8s.io/apiserver v0.28.2 // indirect
k8s.io/cli-runtime v0.28.3 // indirect
k8s.io/component-base v0.28.3 // indirect
k8s.io/klog/v2 v2.100.1 // indirect
k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect
k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 // indirect
oras.land/oras-go v1.2.4 // indirect
k8s.io/apiextensions-apiserver v0.27.1 // indirect
k8s.io/apiserver v0.27.1 // indirect
k8s.io/cli-runtime v0.27.2 // indirect
k8s.io/component-base v0.27.2 // indirect
k8s.io/klog/v2 v2.90.1 // indirect
k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f // indirect
k8s.io/utils v0.0.0-20230313181309-38a27ef9d749 // indirect
oras.land/oras-go v1.2.2 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 // indirect
sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 // indirect
sigs.k8s.io/kustomize/api v0.13.2 // indirect
sigs.k8s.io/kustomize/kyaml v0.14.1 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
sigs.k8s.io/yaml v1.3.0 // indirect
)
// v1.2.0 is taken from github.com/open-policy-agent/opa v0.42.0
// v1.2.0 incompatible with github.com/docker/docker v23.0.0-rc.1+incompatible
replace oras.land/oras-go => oras.land/oras-go v1.2.4
replace oras.land/oras-go => oras.land/oras-go v1.2.3
// v0.3.1-0.20230104082527-d6f58551be3f is taken from github.com/moby/buildkit v0.11.0
// spdx logic write on v0.3.0 and incompatible with v0.3.1-0.20230104082527-d6f58551be3f
replace github.com/spdx/tools-golang => github.com/spdx/tools-golang v0.3.0

903
go.sum

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

View File

@@ -1,196 +0,0 @@
package ai
import (
"context"
"encoding/base64"
"encoding/json"
"fmt"
"strings"
"github.com/fatih/color"
"github.com/k8sgpt-ai/k8sgpt/pkg/cache"
"github.com/k8sgpt-ai/k8sgpt/pkg/util"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/bedrockruntime"
)
// AmazonBedRockClient represents the client for interacting with the Amazon Bedrock service.
type AmazonBedRockClient struct {
client *bedrockruntime.BedrockRuntime
language string
model string
temperature float32
}
// InvokeModelResponseBody represents the response body structure from the model invocation.
type InvokeModelResponseBody struct {
Completion string `json:"completion"`
Stop_reason string `json:"stop_reason"`
}
// Amazon BedRock support region list US East (N. Virginia),US West (Oregon),Asia Pacific (Singapore),Asia Pacific (Tokyo),Europe (Frankfurt)
// https://docs.aws.amazon.com/bedrock/latest/userguide/what-is-bedrock.html#bedrock-regions
const BEDROCK_DEFAULT_REGION = "us-east-1" // default use us-east-1 region
const (
US_East_1 = "us-east-1"
US_West_2 = "us-west-2"
AP_Southeast_1 = "ap-southeast-1"
AP_Northeast_1 = "ap-northeast-1"
EU_Central_1 = "eu-central-1"
)
var BEDROCKER_SUPPORTED_REGION = []string{
US_East_1,
US_West_2,
AP_Southeast_1,
AP_Northeast_1,
EU_Central_1,
}
const (
ModelAnthropicClaudeV2 = "anthropic.claude-v2"
ModelAnthropicClaudeV1 = "anthropic.claude-v1"
ModelAnthropicClaudeInstantV1 = "anthropic.claude-instant-v1"
)
var BEDROCK_MODELS = []string{
ModelAnthropicClaudeV2,
ModelAnthropicClaudeV1,
ModelAnthropicClaudeInstantV1,
}
// GetModelOrDefault check config model
func GetModelOrDefault(model string) string {
// Check if the provided model is in the list
for _, m := range BEDROCK_MODELS {
if m == model {
return model // Return the provided model
}
}
// Return the default model if the provided model is not in the list
return BEDROCK_MODELS[0]
}
// GetModelOrDefault check config region
func GetRegionOrDefault(region string) string {
// Check if the provided model is in the list
for _, m := range BEDROCKER_SUPPORTED_REGION {
if m == region {
return region // Return the provided model
}
}
// Return the default model if the provided model is not in the list
return BEDROCK_DEFAULT_REGION
}
// Configure configures the AmazonBedRockClient with the provided configuration and language.
func (a *AmazonBedRockClient) Configure(config IAIConfig, language string) error {
// Create a new AWS session
providerRegion := GetRegionOrDefault(config.GetProviderRegion())
sess, err := session.NewSession(&aws.Config{
Region: aws.String(providerRegion),
})
if err != nil {
return err
}
// Create a new BedrockRuntime client
a.client = bedrockruntime.New(sess)
a.language = language
a.model = GetModelOrDefault(config.GetModel())
a.temperature = config.GetTemperature()
return nil
}
// GetCompletion sends a request to the model for generating completion based on the provided prompt.
func (a *AmazonBedRockClient) GetCompletion(ctx context.Context, prompt string, promptTmpl string) (string, error) {
// Prepare the input data for the model invocation
request := map[string]interface{}{
"prompt": fmt.Sprintf("\n\nHuman: %s \n\nAssistant:", prompt),
"max_tokens_to_sample": 1024,
"temperature": a.temperature,
"top_p": 0.9,
}
body, err := json.Marshal(request)
if err != nil {
return "", err
}
// Build the parameters for the model invocation
params := &bedrockruntime.InvokeModelInput{
Body: body,
ModelId: aws.String(a.model),
ContentType: aws.String("application/json"),
Accept: aws.String("application/json"),
}
// Invoke the model
resp, err := a.client.InvokeModelWithContext(ctx, params)
if err != nil {
return "", err
}
// Parse the response body
output := &InvokeModelResponseBody{}
err = json.Unmarshal(resp.Body, output)
if err != nil {
return "", err
}
return output.Completion, nil
}
// Parse generates a completion for the provided prompt using the Amazon Bedrock model.
func (a *AmazonBedRockClient) Parse(ctx context.Context, prompt []string, cache cache.ICache, promptTmpl string) (string, error) {
inputKey := strings.Join(prompt, " ")
// Check for cached data
cacheKey := util.GetCacheKey(a.GetName(), a.language, inputKey)
if !cache.IsCacheDisabled() && cache.Exists(cacheKey) {
response, err := cache.Load(cacheKey)
if err != nil {
return "", err
}
if response != "" {
output, err := base64.StdEncoding.DecodeString(response)
if err != nil {
color.Red("error decoding cached data: %v", err)
return "", nil
}
return string(output), nil
}
}
response, err := a.GetCompletion(ctx, inputKey, promptTmpl)
if err != nil {
return "", err
}
err = cache.Store(cacheKey, base64.StdEncoding.EncodeToString([]byte(response)))
if err != nil {
color.Red("error storing value to cache: %v", err)
return "", nil
}
return response, nil
}
// GetName returns the name of the AmazonBedRockClient.
func (a *AmazonBedRockClient) GetName() string {
return "amazonbedrock"
}

View File

@@ -1,170 +0,0 @@
/*
Copyright 2023 The K8sGPT Authors.
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.
*/
package ai
import (
"context"
"encoding/base64"
"fmt"
"strings"
"encoding/json"
"github.com/fatih/color"
"github.com/k8sgpt-ai/k8sgpt/pkg/cache"
"github.com/k8sgpt-ai/k8sgpt/pkg/util"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/sagemakerruntime"
)
type SageMakerAIClient struct {
client *sagemakerruntime.SageMakerRuntime
language string
model string
temperature float32
endpoint string
topP float32
maxTokens int
}
type Generations []struct {
Generation struct {
Role string `json:"role"`
Content string `json:"content"`
} `json:"generation"`
}
type Request struct {
Inputs [][]Message `json:"inputs"`
Parameters Parameters `json:"parameters"`
}
type Message struct {
Role string `json:"role"`
Content string `json:"content"`
}
type Parameters struct {
MaxNewTokens int `json:"max_new_tokens"`
TopP float64 `json:"top_p"`
Temperature float64 `json:"temperature"`
}
func (c *SageMakerAIClient) Configure(config IAIConfig, language string) error {
// Create a new AWS session
sess := session.Must(session.NewSessionWithOptions(session.Options{
Config: aws.Config{Region: aws.String(config.GetProviderRegion())},
SharedConfigState: session.SharedConfigEnable,
}))
c.language = language
// Create a new SageMaker runtime client
c.client = sagemakerruntime.New(sess)
c.model = config.GetModel()
c.endpoint = config.GetEndpointName()
c.temperature = config.GetTemperature()
c.maxTokens = config.GetMaxTokens()
c.topP = config.GetTopP()
return nil
}
func (c *SageMakerAIClient) GetCompletion(ctx context.Context, prompt string, promptTmpl string) (string, error) {
// Create a completion request
if len(promptTmpl) == 0 {
promptTmpl = PromptMap["default"]
}
request := Request{
Inputs: [][]Message{
{
{Role: "system", Content: "DEFAULT_PROMPT"},
{Role: "user", Content: fmt.Sprintf(promptTmpl, c.language, prompt)},
},
},
Parameters: Parameters{
MaxNewTokens: int(c.maxTokens),
TopP: float64(c.topP),
Temperature: float64(c.temperature),
},
}
// Convert request to []byte
bytesData, err := json.Marshal(request)
if err != nil {
return "", err
}
// Create an input object
input := &sagemakerruntime.InvokeEndpointInput{
Body: bytesData,
EndpointName: aws.String(c.endpoint),
ContentType: aws.String("application/json"), // Set the content type as per your model's requirements
Accept: aws.String("application/json"), // Set the accept type as per your model's requirements
CustomAttributes: aws.String("accept_eula=true"),
}
// Call the InvokeEndpoint function
result, err := c.client.InvokeEndpoint(input)
if err != nil {
return "", err
}
// // Define a slice of Generations
var generations Generations
err = json.Unmarshal([]byte(string(result.Body)), &generations)
if err != nil {
return "", err
}
// Check for length of generations
if len(generations) != 1 {
return "", fmt.Errorf("Expected exactly one generation, but got %d", len(generations))
}
// Access the content
content := generations[0].Generation.Content
return content, nil
}
func (a *SageMakerAIClient) Parse(ctx context.Context, prompt []string, cache cache.ICache, promptTmpl string) (string, error) {
// parse the text with the AI backend
inputKey := strings.Join(prompt, " ")
// Check for cached data
sEnc := base64.StdEncoding.EncodeToString([]byte(inputKey))
cacheKey := util.GetCacheKey(a.GetName(), a.language, sEnc)
response, err := a.GetCompletion(ctx, inputKey, promptTmpl)
if err != nil {
color.Red("error getting completion: %v", err)
return "", err
}
err = cache.Store(cacheKey, base64.StdEncoding.EncodeToString([]byte(response)))
if err != nil {
color.Red("error storing value to cache: %v", err)
return "", err
}
return response, nil
}
func (a *SageMakerAIClient) GetName() string {
return "amazonsagemaker"
}

View File

@@ -16,26 +16,16 @@ import (
)
type AzureAIClient struct {
client *openai.Client
language string
model string
temperature float32
client *openai.Client
language string
model string
}
func (c *AzureAIClient) Configure(config IAIConfig, lang string) error {
token := config.GetPassword()
baseURL := config.GetBaseURL()
engine := config.GetEngine()
defaultConfig := openai.DefaultAzureConfig(token, baseURL)
defaultConfig.AzureModelMapperFunc = func(model string) string {
// If you use a deployment name different from the model name, you can customize the AzureModelMapperFunc function
azureModelMapping := map[string]string{
model: engine,
}
return azureModelMapping[model]
}
defaultConfig := openai.DefaultAzureConfig(token, baseURL, engine)
client := openai.NewClientWithConfig(defaultConfig)
if client == nil {
return errors.New("error creating Azure OpenAI client")
@@ -43,7 +33,6 @@ func (c *AzureAIClient) Configure(config IAIConfig, lang string) error {
c.language = lang
c.client = client
c.model = config.GetModel()
c.temperature = config.GetTemperature()
return nil
}
@@ -53,11 +42,10 @@ func (c *AzureAIClient) GetCompletion(ctx context.Context, prompt string, prompt
Model: c.model,
Messages: []openai.ChatCompletionMessage{
{
Role: openai.ChatMessageRoleUser,
Role: "user",
Content: fmt.Sprintf(default_prompt, c.language, prompt),
},
},
Temperature: c.temperature,
})
if err != nil {
return "", err

View File

@@ -1,118 +0,0 @@
/*
Copyright 2023 The K8sGPT Authors.
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.
*/
package ai
import (
"context"
"encoding/base64"
"errors"
"fmt"
"strings"
"github.com/cohere-ai/cohere-go"
"github.com/fatih/color"
"github.com/k8sgpt-ai/k8sgpt/pkg/cache"
"github.com/k8sgpt-ai/k8sgpt/pkg/util"
)
type CohereClient struct {
client *cohere.Client
language string
model string
temperature float32
}
func (c *CohereClient) Configure(config IAIConfig, language string) error {
token := config.GetPassword()
client, err := cohere.CreateClient(token)
if err != nil {
return err
}
baseURL := config.GetBaseURL()
if baseURL != "" {
client.BaseURL = baseURL
}
if client == nil {
return errors.New("error creating Cohere client")
}
c.language = language
c.client = client
c.model = config.GetModel()
c.temperature = config.GetTemperature()
return nil
}
func (c *CohereClient) GetCompletion(ctx context.Context, prompt, promptTmpl string) (string, error) {
// Create a completion request
if len(promptTmpl) == 0 {
promptTmpl = PromptMap["default"]
}
resp, err := c.client.Generate(cohere.GenerateOptions{
Model: c.model,
Prompt: fmt.Sprintf(strings.TrimSpace(promptTmpl), c.language, prompt),
MaxTokens: cohere.Uint(2048),
Temperature: cohere.Float64(float64(c.temperature)),
K: cohere.Int(0),
StopSequences: []string{},
ReturnLikelihoods: "NONE",
})
if err != nil {
return "", err
}
return resp.Generations[0].Text, nil
}
func (a *CohereClient) Parse(ctx context.Context, prompt []string, cache cache.ICache, promptTmpl string) (string, error) {
inputKey := strings.Join(prompt, " ")
// Check for cached data
cacheKey := util.GetCacheKey(a.GetName(), a.language, inputKey)
if !cache.IsCacheDisabled() && cache.Exists(cacheKey) {
response, err := cache.Load(cacheKey)
if err != nil {
return "", err
}
if response != "" {
output, err := base64.StdEncoding.DecodeString(response)
if err != nil {
color.Red("error decoding cached data: %v", err)
return "", nil
}
return string(output), nil
}
}
response, err := a.GetCompletion(ctx, inputKey, promptTmpl)
if err != nil {
return "", err
}
err = cache.Store(cacheKey, base64.StdEncoding.EncodeToString([]byte(response)))
if err != nil {
color.Red("error storing value to cache: %v", err)
return "", nil
}
return response, nil
}
func (a *CohereClient) GetName() string {
return "cohere"
}

View File

@@ -25,18 +25,12 @@ var (
&AzureAIClient{},
&LocalAIClient{},
&NoOpAIClient{},
&CohereClient{},
&AmazonBedRockClient{},
&SageMakerAIClient{},
}
Backends = []string{
"openai",
"localai",
"azureopenai",
"noopai",
"cohere",
"amazonbedrock",
"amazonsagemaker",
}
)
@@ -51,12 +45,7 @@ type IAIConfig interface {
GetPassword() string
GetModel() string
GetBaseURL() string
GetEndpointName() string
GetEngine() string
GetTemperature() float32
GetProviderRegion() string
GetTopP() float32
GetMaxTokens() int
}
func NewClient(provider string) IAI {
@@ -75,34 +64,17 @@ type AIConfiguration struct {
}
type AIProvider struct {
Name string `mapstructure:"name"`
Model string `mapstructure:"model"`
Password string `mapstructure:"password" yaml:"password,omitempty"`
BaseURL string `mapstructure:"baseurl" yaml:"baseurl,omitempty"`
EndpointName string `mapstructure:"endpointname" yaml:"endpointname,omitempty"`
Engine string `mapstructure:"engine" yaml:"engine,omitempty"`
Temperature float32 `mapstructure:"temperature" yaml:"temperature,omitempty"`
ProviderRegion string `mapstructure:"providerregion" yaml:"providerregion,omitempty"`
TopP float32 `mapstructure:"topp" yaml:"topp,omitempty"`
MaxTokens int `mapstructure:"maxtokens" yaml:"maxtokens,omitempty"`
Name string `mapstructure:"name"`
Model string `mapstructure:"model"`
Password string `mapstructure:"password" yaml:"password,omitempty"`
BaseURL string `mapstructure:"baseurl" yaml:"baseurl,omitempty"`
Engine string `mapstructure:"engine" yaml:"engine,omitempty"`
}
func (p *AIProvider) GetBaseURL() string {
return p.BaseURL
}
func (p *AIProvider) GetEndpointName() string {
return p.EndpointName
}
func (p *AIProvider) GetTopP() float32 {
return p.TopP
}
func (p *AIProvider) GetMaxTokens() int {
return p.MaxTokens
}
func (p *AIProvider) GetPassword() string {
return p.Password
}
@@ -114,21 +86,7 @@ func (p *AIProvider) GetModel() string {
func (p *AIProvider) GetEngine() string {
return p.Engine
}
func (p *AIProvider) GetTemperature() float32 {
return p.Temperature
}
func (p *AIProvider) GetProviderRegion() string {
return p.ProviderRegion
}
var passwordlessProviders = []string{"localai", "amazonsagemaker", "amazonbedrock"}
func NeedPassword(backend string) bool {
for _, b := range passwordlessProviders {
if b == backend {
return false
}
}
return true
return backend != "localai"
}

View File

@@ -29,20 +29,11 @@ import (
)
type OpenAIClient struct {
client *openai.Client
language string
model string
temperature float32
client *openai.Client
language string
model string
}
const (
// OpenAI completion parameters
maxToken = 2048
presencePenalty = 0.0
frequencyPenalty = 0.0
topP = 1.0
)
func (c *OpenAIClient) Configure(config IAIConfig, language string) error {
token := config.GetPassword()
defaultConfig := openai.DefaultConfig(token)
@@ -59,7 +50,6 @@ func (c *OpenAIClient) Configure(config IAIConfig, language string) error {
c.language = language
c.client = client
c.model = config.GetModel()
c.temperature = config.GetTemperature()
return nil
}
@@ -76,11 +66,6 @@ func (c *OpenAIClient) GetCompletion(ctx context.Context, prompt string, promptT
Content: fmt.Sprintf(promptTmpl, c.language, prompt),
},
},
Temperature: c.temperature,
MaxTokens: maxToken,
PresencePenalty: presencePenalty,
FrequencyPenalty: frequencyPenalty,
TopP: topP,
})
if err != nil {
return "", err

View File

@@ -6,12 +6,10 @@ const (
Error: {Explain error here}
Solution: {Step by step solution here}
`
trivy_vuln_prompt = "Explain the following trivy scan result and the detail risk or root cause of the CVE ID, then provide a solution. Response in %s: %s"
trivy_conf_prompt = "Explain the following trivy scan result and the detail risk or root cause of the security check, then provide a solution."
trivy_prompt = "Explain the following trivy scan result and the detail risk or root cause of the CVE ID, then provide a solution. Response in %s: %s"
)
var PromptMap = map[string]string{
"default": default_prompt,
"VulnerabilityReport": trivy_vuln_prompt, // for Trivy integration, the key should match `Result.Kind` in pkg/common/types.go
"ConfigAuditReport": trivy_conf_prompt,
"VulnerabilityReport": trivy_prompt, // for Trivy intergration, the key should match `Result.Kind` in pkg/common/types.go
}

View File

@@ -77,6 +77,11 @@ func (a *Analysis) textOutput() ([]byte, error) {
output.WriteString(fmt.Sprintf("%s %s(%s)\n", color.CyanString("%d", n),
color.YellowString(result.Name), color.CyanString(result.ParentObject)))
for _, err := range result.Error {
if hasAIFailure(err.Text) {
err.Text = "Unable to remediate issue. Please refer to the documentation for more information."
}
output.WriteString(fmt.Sprintf("- %s %s\n", color.RedString("Error:"), color.RedString(err.Text)))
if err.KubernetesDoc != "" {
output.WriteString(fmt.Sprintf(" %s %s\n", color.RedString("Kubernetes Doc:"), color.RedString(err.KubernetesDoc)))
@@ -86,3 +91,7 @@ func (a *Analysis) textOutput() ([]byte, error) {
}
return []byte(output.String()), nil
}
func hasAIFailure(text string) bool {
return strings.Contains(text, "As an AI language model")
}

View File

@@ -32,17 +32,15 @@ var (
)
var coreAnalyzerMap = map[string]common.IAnalyzer{
"Pod": PodAnalyzer{},
"Deployment": DeploymentAnalyzer{},
"ReplicaSet": ReplicaSetAnalyzer{},
"PersistentVolumeClaim": PvcAnalyzer{},
"Service": ServiceAnalyzer{},
"Ingress": IngressAnalyzer{},
"StatefulSet": StatefulSetAnalyzer{},
"CronJob": CronJobAnalyzer{},
"Node": NodeAnalyzer{},
"ValidatingWebhookConfiguration": ValidatingWebhookAnalyzer{},
"MutatingWebhookConfiguration": MutatingWebhookAnalyzer{},
"Pod": PodAnalyzer{},
"Deployment": DeploymentAnalyzer{},
"ReplicaSet": ReplicaSetAnalyzer{},
"PersistentVolumeClaim": PvcAnalyzer{},
"Service": ServiceAnalyzer{},
"Ingress": IngressAnalyzer{},
"StatefulSet": StatefulSetAnalyzer{},
"CronJob": CronJobAnalyzer{},
"Node": NodeAnalyzer{},
}
var additionalAnalyzerMap = map[string]common.IAnalyzer{
@@ -73,7 +71,7 @@ func ListFilters() ([]string, []string, []string) {
fmt.Println(color.RedString(err.Error()))
os.Exit(1)
}
integrationAnalyzers = append(integrationAnalyzers, in.GetAnalyzerName()...)
integrationAnalyzers = append(integrationAnalyzers, in.GetAnalyzerName())
}
}

View File

@@ -98,28 +98,26 @@ func (IngressAnalyzer) Analyze(a common.Analyzer) ([]common.Result, error) {
// loop over rules
for _, rule := range ing.Spec.Rules {
// loop over HTTP paths
if rule.HTTP != nil {
for _, path := range rule.HTTP.Paths {
_, err := a.Client.GetClient().CoreV1().Services(ing.Namespace).Get(a.Context, path.Backend.Service.Name, metav1.GetOptions{})
if err != nil {
doc := apiDoc.GetApiDocV2("spec.rules.http.paths.backend.service")
// loop over paths
for _, path := range rule.HTTP.Paths {
_, err := a.Client.GetClient().CoreV1().Services(ing.Namespace).Get(a.Context, path.Backend.Service.Name, metav1.GetOptions{})
if err != nil {
doc := apiDoc.GetApiDocV2("spec.rules.http.paths.backend.service")
failures = append(failures, common.Failure{
Text: fmt.Sprintf("Ingress uses the service %s/%s which does not exist.", ing.Namespace, path.Backend.Service.Name),
KubernetesDoc: doc,
Sensitive: []common.Sensitive{
{
Unmasked: ing.Namespace,
Masked: util.MaskString(ing.Namespace),
},
{
Unmasked: path.Backend.Service.Name,
Masked: util.MaskString(path.Backend.Service.Name),
},
failures = append(failures, common.Failure{
Text: fmt.Sprintf("Ingress uses the service %s/%s which does not exist.", ing.Namespace, path.Backend.Service.Name),
KubernetesDoc: doc,
Sensitive: []common.Sensitive{
{
Unmasked: ing.Namespace,
Masked: util.MaskString(ing.Namespace),
},
})
}
{
Unmasked: path.Backend.Service.Name,
Masked: util.MaskString(path.Backend.Service.Name),
},
},
})
}
}
}

View File

@@ -1,155 +0,0 @@
/*
Copyright 2023 The K8sGPT Authors.
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.
*/
package analyzer
import (
"context"
"fmt"
"github.com/k8sgpt-ai/k8sgpt/pkg/common"
"github.com/k8sgpt-ai/k8sgpt/pkg/kubernetes"
"github.com/k8sgpt-ai/k8sgpt/pkg/util"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
)
type MutatingWebhookAnalyzer struct{}
func (MutatingWebhookAnalyzer) Analyze(a common.Analyzer) ([]common.Result, error) {
kind := "MutatingWebhookConfiguration"
apiDoc := kubernetes.K8sApiReference{
Kind: kind,
ApiVersion: schema.GroupVersion{
Group: "apps",
Version: "v1",
},
OpenapiSchema: a.OpenapiSchema,
}
AnalyzerErrorsMetric.DeletePartialMatch(map[string]string{
"analyzer_name": kind,
})
mutatingWebhooks, err := a.Client.GetClient().AdmissionregistrationV1().MutatingWebhookConfigurations().List(context.Background(), v1.ListOptions{})
if err != nil {
return nil, err
}
var preAnalysis = map[string]common.PreAnalysis{}
for _, webhookConfig := range mutatingWebhooks.Items {
for _, webhook := range webhookConfig.Webhooks {
var failures []common.Failure
if webhook.ClientConfig.Service == nil {
continue
}
svc := webhook.ClientConfig.Service
// Get the service
service, err := a.Client.GetClient().CoreV1().Services(svc.Namespace).Get(context.Background(), svc.Name, v1.GetOptions{})
if err != nil {
// If the service is not found, we can't check the pods
failures = append(failures, common.Failure{
Text: fmt.Sprintf("Service %s not found as mapped to by Mutating Webhook %s", svc.Name, webhook.Name),
KubernetesDoc: apiDoc.GetApiDocV2("spec.webhook.clientConfig.service"),
Sensitive: []common.Sensitive{
{
Unmasked: webhookConfig.Namespace,
Masked: util.MaskString(webhookConfig.Namespace),
},
{
Unmasked: svc.Name,
Masked: util.MaskString(svc.Name),
},
},
})
continue
}
// When Service selectors are empty we defer to service analyser
if len(service.Spec.Selector) == 0 {
continue
}
// Get pods within service
pods, err := a.Client.GetClient().CoreV1().Pods(svc.Namespace).List(context.Background(), v1.ListOptions{
LabelSelector: util.MapToString(service.Spec.Selector),
})
if err != nil {
return nil, err
}
if len(pods.Items) == 0 {
failures = append(failures, common.Failure{
Text: fmt.Sprintf("No active pods found within service %s as mapped to by Mutating Webhook %s", svc.Name, webhook.Name),
KubernetesDoc: apiDoc.GetApiDocV2("spec.webhook.clientConfig.service"),
Sensitive: []common.Sensitive{
{
Unmasked: webhookConfig.Namespace,
Masked: util.MaskString(webhookConfig.Namespace),
},
},
})
}
for _, pod := range pods.Items {
if pod.Status.Phase != "Running" {
doc := apiDoc.GetApiDocV2("spec.webhook")
failures = append(failures, common.Failure{
Text: fmt.Sprintf(
"Mutating Webhook (%s) is pointing to an inactive receiver pod (%s)",
webhook.Name,
pod.Name,
),
KubernetesDoc: doc,
Sensitive: []common.Sensitive{
{
Unmasked: webhookConfig.Namespace,
Masked: util.MaskString(webhookConfig.Namespace),
},
{
Unmasked: webhook.Name,
Masked: util.MaskString(webhook.Name),
},
{
Unmasked: pod.Name,
Masked: util.MaskString(pod.Name),
},
},
})
}
}
if len(failures) > 0 {
preAnalysis[fmt.Sprintf("%s/%s", webhookConfig.Namespace, webhook.Name)] = common.PreAnalysis{
MutatingWebhook: webhookConfig,
FailureDetails: failures,
}
AnalyzerErrorsMetric.WithLabelValues(kind, webhook.Name, webhookConfig.Namespace).Set(float64(len(failures)))
}
}
}
for key, value := range preAnalysis {
var currentAnalysis = common.Result{
Kind: kind,
Name: key,
Error: value.FailureDetails,
}
parent, _ := util.GetParent(a.Client, value.MutatingWebhook.ObjectMeta)
currentAnalysis.ParentObject = parent
a.Results = append(a.Results, currentAnalysis)
}
return a.Results, nil
}

View File

@@ -58,23 +58,21 @@ func (PdbAnalyzer) Analyze(a common.Analyzer) ([]common.Result, error) {
if pdb.Spec.MinAvailable != nil {
doc = apiDoc.GetApiDocV2("spec.minAvailable")
}
if pdb.Spec.Selector != nil && pdb.Spec.Selector.MatchLabels != nil {
for k, v := range pdb.Spec.Selector.MatchLabels {
failures = append(failures, common.Failure{
Text: fmt.Sprintf("%s, expected pdb pod label %s=%s", pdb.Status.Conditions[0].Reason, k, v),
KubernetesDoc: doc,
Sensitive: []common.Sensitive{
{
Unmasked: k,
Masked: util.MaskString(k),
},
{
Unmasked: v,
Masked: util.MaskString(v),
},
for k, v := range pdb.Spec.Selector.MatchLabels {
failures = append(failures, common.Failure{
Text: fmt.Sprintf("%s, expected pdb pod label %s=%s", pdb.Status.Conditions[0].Reason, k, v),
KubernetesDoc: doc,
Sensitive: []common.Sensitive{
{
Unmasked: k,
Masked: util.MaskString(k),
},
})
}
{
Unmasked: v,
Masked: util.MaskString(v),
},
},
})
}
}

View File

@@ -17,12 +17,10 @@ import (
"fmt"
"github.com/fatih/color"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/tools/leaderelection/resourcelock"
"github.com/k8sgpt-ai/k8sgpt/pkg/common"
"github.com/k8sgpt-ai/k8sgpt/pkg/kubernetes"
"github.com/k8sgpt-ai/k8sgpt/pkg/util"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
)
@@ -57,10 +55,6 @@ func (ServiceAnalyzer) Analyze(a common.Analyzer) ([]common.Result, error) {
// Check for empty service
if len(ep.Subsets) == 0 {
if _, ok := ep.Annotations[resourcelock.LeaderElectionRecordAnnotationKey]; ok {
continue
}
svc, err := a.Client.GetClient().CoreV1().Services(ep.Namespace).Get(a.Context, ep.Name, metav1.GetOptions{})
if err != nil {
color.Yellow("Service %s/%s does not exist", ep.Namespace, ep.Name)

View File

@@ -1,153 +0,0 @@
/*
Copyright 2023 The K8sGPT Authors.
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.
*/
package analyzer
import (
"context"
"fmt"
"github.com/k8sgpt-ai/k8sgpt/pkg/common"
"github.com/k8sgpt-ai/k8sgpt/pkg/kubernetes"
"github.com/k8sgpt-ai/k8sgpt/pkg/util"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
)
type ValidatingWebhookAnalyzer struct{}
func (ValidatingWebhookAnalyzer) Analyze(a common.Analyzer) ([]common.Result, error) {
kind := "ValidatingWebhookConfgiguration"
apiDoc := kubernetes.K8sApiReference{
Kind: kind,
ApiVersion: schema.GroupVersion{
Group: "apps",
Version: "v1",
},
OpenapiSchema: a.OpenapiSchema,
}
AnalyzerErrorsMetric.DeletePartialMatch(map[string]string{
"analyzer_name": kind,
})
validatingWebhooks, err := a.Client.GetClient().AdmissionregistrationV1().ValidatingWebhookConfigurations().List(context.Background(), v1.ListOptions{})
if err != nil {
return nil, err
}
var preAnalysis = map[string]common.PreAnalysis{}
for _, webhookConfig := range validatingWebhooks.Items {
for _, webhook := range webhookConfig.Webhooks {
var failures []common.Failure
if webhook.ClientConfig.Service == nil {
continue
}
svc := webhook.ClientConfig.Service
// Get the service
service, err := a.Client.GetClient().CoreV1().Services(svc.Namespace).Get(context.Background(), svc.Name, v1.GetOptions{})
if err != nil {
// If the service is not found, we can't check the pods
failures = append(failures, common.Failure{
Text: fmt.Sprintf("Service %s not found as mapped to by Validating Webhook %s", svc.Name, webhook.Name),
KubernetesDoc: apiDoc.GetApiDocV2("spec.webhook.clientConfig.service"),
Sensitive: []common.Sensitive{
{
Unmasked: webhookConfig.Namespace,
Masked: util.MaskString(webhookConfig.Namespace),
},
{
Unmasked: svc.Name,
Masked: util.MaskString(svc.Name),
},
},
})
continue
}
// When Service selectors are empty we defer to service analyser
if len(service.Spec.Selector) == 0 {
continue
}
// Get pods within service
pods, err := a.Client.GetClient().CoreV1().Pods(svc.Namespace).List(context.Background(), v1.ListOptions{
LabelSelector: util.MapToString(service.Spec.Selector),
})
if err != nil {
return nil, err
}
if len(pods.Items) == 0 {
failures = append(failures, common.Failure{
Text: fmt.Sprintf("No active pods found within service %s as mapped to by Validating Webhook %s", svc.Name, webhook.Name),
KubernetesDoc: apiDoc.GetApiDocV2("spec.webhook.clientConfig.service"),
Sensitive: []common.Sensitive{
{
Unmasked: webhookConfig.Namespace,
Masked: util.MaskString(webhookConfig.Namespace),
},
},
})
}
for _, pod := range pods.Items {
if pod.Status.Phase != "Running" {
doc := apiDoc.GetApiDocV2("spec.webhook")
failures = append(failures, common.Failure{
Text: fmt.Sprintf(
"Validating Webhook (%s) is pointing to an inactive receiver pod (%s)",
webhook.Name,
pod.Name,
),
KubernetesDoc: doc,
Sensitive: []common.Sensitive{
{
Unmasked: webhookConfig.Namespace,
Masked: util.MaskString(webhookConfig.Namespace),
},
{
Unmasked: webhook.Name,
Masked: util.MaskString(webhook.Name),
},
{
Unmasked: pod.Name,
Masked: util.MaskString(pod.Name),
},
},
})
}
}
if len(failures) > 0 {
preAnalysis[fmt.Sprintf("%s/%s", webhookConfig.Namespace, webhook.Name)] = common.PreAnalysis{
ValidatingWebhook: webhookConfig,
FailureDetails: failures,
}
AnalyzerErrorsMetric.WithLabelValues(kind, webhook.Name, webhookConfig.Namespace).Set(float64(len(failures)))
}
}
}
for key, value := range preAnalysis {
var currentAnalysis = common.Result{
Kind: kind,
Name: key,
Error: value.FailureDetails,
}
parent, _ := util.GetParent(a.Client, value.ValidatingWebhook.ObjectMeta)
currentAnalysis.ParentObject = parent
a.Results = append(a.Results, currentAnalysis)
}
return a.Results, nil
}

View File

@@ -1,138 +0,0 @@
package cache
import (
"bytes"
"context"
"fmt"
"log"
"strings"
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
"github.com/spf13/viper"
)
// Generate ICache implementation
type AzureCache struct {
ctx context.Context
noCache bool
containerName string
session *azblob.Client
}
func (s *AzureCache) Store(key string, data string) error {
// Store the object as a new file in the Azure blob storage with data as the content
cacheData := []byte(data)
_, err := s.session.UploadBuffer(s.ctx, s.containerName, key, cacheData, &azblob.UploadBufferOptions{})
return err
}
func (s *AzureCache) Load(key string) (string, error) {
// Load blob file contents
load, err := s.session.DownloadStream(s.ctx, s.containerName, key, nil)
if err != nil {
return "", err
}
data := bytes.Buffer{}
retryReader := load.NewRetryReader(s.ctx, &azblob.RetryReaderOptions{})
_, err = data.ReadFrom(retryReader)
if err != nil {
return "", err
}
if err := retryReader.Close(); err != nil {
return "", err
}
return data.String(), nil
}
func (s *AzureCache) List() ([]string, error) {
// List the files in the blob containerName
files := []string{}
pager := s.session.NewListBlobsFlatPager(s.containerName, &azblob.ListBlobsFlatOptions{
Include: azblob.ListBlobsInclude{Snapshots: false, Versions: false},
})
for pager.More() {
resp, err := pager.NextPage(s.ctx)
if err != nil {
return nil, err
}
for _, blob := range resp.Segment.BlobItems {
files = append(files, *blob.Name)
}
}
return files, nil
}
func (s *AzureCache) Exists(key string) bool {
// Check if the object exists in the blob storage
pager := s.session.NewListBlobsFlatPager(s.containerName, &azblob.ListBlobsFlatOptions{
Include: azblob.ListBlobsInclude{Snapshots: false, Versions: false},
})
for pager.More() {
resp, err := pager.NextPage(s.ctx)
if err != nil {
return false
}
for _, blob := range resp.Segment.BlobItems {
if *blob.Name == key {
return true
}
}
}
return false
}
func (s *AzureCache) IsCacheDisabled() bool {
return s.noCache
}
func NewAzureCache(nocache bool) ICache {
ctx := context.Background()
var cache CacheProvider
err := viper.UnmarshalKey("cache", &cache)
if err != nil {
panic(err)
}
if cache.ContainerName == "" {
log.Fatal("Azure Container name not configured")
}
if cache.StorageAccount == "" {
log.Fatal("Azure Storage account not configured")
}
// We assume that Storage account is already in place
blobUrl := fmt.Sprintf("https://%s.blob.core.windows.net/", cache.StorageAccount)
credential, err := azidentity.NewDefaultAzureCredential(nil)
if err != nil {
log.Fatal(err)
}
client, err := azblob.NewClient(blobUrl, credential, nil)
if err != nil {
log.Fatal(err)
}
// Try to create the blob container
_, err = client.CreateContainer(ctx, cache.ContainerName, nil)
if err != nil {
// TODO: Maybe there is a better way to check this?
// docs: https://pkg.go.dev/github.com/Azure/azure-storage-blob-go/azblob
if strings.Contains(err.Error(), "ContainerAlreadyExists") {
// do nothing
} else {
log.Fatal(err)
}
}
return &AzureCache{
ctx: ctx,
noCache: nocache,
containerName: cache.ContainerName,
session: client,
}
}

78
pkg/cache/cache.go vendored
View File

@@ -1,20 +1,11 @@
package cache
import (
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"errors"
"github.com/spf13/viper"
)
type CacheType string
const (
Azure CacheType = "azure"
S3 CacheType = "s3"
FileBased CacheType = "file"
)
type ICache interface {
Store(key string, data string) error
Load(key string) (string, error)
@@ -23,68 +14,45 @@ type ICache interface {
IsCacheDisabled() bool
}
func New(noCache bool, remoteCache CacheType) ICache {
switch remoteCache {
case S3:
func New(noCache bool, remoteCache bool) ICache {
if remoteCache {
return NewS3Cache(noCache)
case Azure:
return NewAzureCache(noCache)
case FileBased:
return &FileBasedCache{
noCache: noCache,
}
default:
return &FileBasedCache{
noCache: noCache,
}
}
return &FileBasedCache{
noCache: noCache,
}
}
// CacheProvider is the configuration for the cache provider when using a remote cache
type CacheProvider struct {
BucketName string `mapstructure:"bucketname" yaml:"bucketname,omitempty"`
Region string `mapstructure:"region" yaml:"region,omitempty"`
StorageAccount string `mapstructure:"storageaccount" yaml:"storageaccount,omitempty"`
ContainerName string `mapstructure:"container" yaml:"container,omitempty"`
BucketName string `mapstructure:"bucketname"`
Region string `mapstructure:"region"`
}
// NewCacheProvider constructs a new cache struct
func NewCacheProvider(bucketname, region, storageaccount, containername string) CacheProvider {
return CacheProvider{
BucketName: bucketname,
Region: region,
StorageAccount: storageaccount,
ContainerName: containername,
}
}
// If we have set a remote cache, return the remote cache type
func RemoteCacheEnabled() (CacheType, error) {
func RemoteCacheEnabled() (bool, error) {
// load remote cache if it is configured
var cache CacheProvider
err := viper.UnmarshalKey("cache", &cache)
if err != nil {
return "", err
return false, err
}
if cache.BucketName != "" && cache.Region != "" {
return S3, nil
} else if cache.StorageAccount != "" && cache.ContainerName != "" {
return Azure, nil
return true, nil
}
return FileBased, nil
return false, nil
}
func AddRemoteCache(cache CacheProvider) error {
func AddRemoteCache(bucketName string, region string) error {
var cacheInfo CacheProvider
err := viper.UnmarshalKey("cache", &cacheInfo)
if err != nil {
return err
}
cacheInfo.BucketName = cache.BucketName
cacheInfo.Region = cache.Region
cacheInfo.StorageAccount = cache.StorageAccount
cacheInfo.ContainerName = cache.ContainerName
if cacheInfo.BucketName != "" {
return errors.New("Error: a cache is already configured, please remove it first")
}
cacheInfo.BucketName = bucketName
cacheInfo.Region = region
viper.Set("cache", cacheInfo)
err = viper.WriteConfig()
if err != nil {
@@ -93,21 +61,21 @@ func AddRemoteCache(cache CacheProvider) error {
return nil
}
func RemoveRemoteCache() error {
func RemoveRemoteCache(bucketName string) error {
var cacheInfo CacheProvider
err := viper.UnmarshalKey("cache", &cacheInfo)
if err != nil {
return status.Error(codes.Internal, "cache unmarshal")
return err
}
if cacheInfo.BucketName == "" && cacheInfo.ContainerName == "" && cacheInfo.StorageAccount == "" {
return status.Error(codes.Internal, "no remote cache configured")
if cacheInfo.BucketName == "" {
return errors.New("Error: no cache is configured")
}
cacheInfo = CacheProvider{}
viper.Set("cache", cacheInfo)
err = viper.WriteConfig()
if err != nil {
return status.Error(codes.Internal, "unable to write config")
return err
}
return nil

12
pkg/cache/s3_based.go vendored
View File

@@ -2,7 +2,6 @@ package cache
import (
"bytes"
"log"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
@@ -80,13 +79,13 @@ func NewS3Cache(nocache bool) ICache {
var cache CacheProvider
err := viper.UnmarshalKey("cache", &cache)
if err != nil {
log.Fatal(err)
panic(err)
}
if cache.BucketName == "" {
log.Fatal("Bucket name not configured")
panic("Bucket name not configured")
}
if cache.Region == "" {
log.Fatal("Region not configured")
panic("Region not configured")
}
sess := session.Must(session.NewSessionWithOptions(session.Options{
@@ -103,9 +102,12 @@ func NewS3Cache(nocache bool) ICache {
Bucket: aws.String(cache.BucketName),
})
if err != nil {
_, _ = s.CreateBucket(&s3.CreateBucketInput{
_, err = s.CreateBucket(&s3.CreateBucketInput{
Bucket: aws.String(cache.BucketName),
})
if err != nil {
panic(err)
}
}
return &S3Cache{

View File

@@ -20,7 +20,6 @@ import (
openapi_v2 "github.com/google/gnostic/openapiv2"
"github.com/k8sgpt-ai/k8sgpt/pkg/ai"
"github.com/k8sgpt-ai/k8sgpt/pkg/kubernetes"
regv1 "k8s.io/api/admissionregistration/v1"
appsv1 "k8s.io/api/apps/v1"
autov1 "k8s.io/api/autoscaling/v1"
v1 "k8s.io/api/core/v1"
@@ -55,11 +54,8 @@ type PreAnalysis struct {
StatefulSet appsv1.StatefulSet
NetworkPolicy networkv1.NetworkPolicy
Node v1.Node
ValidatingWebhook regv1.ValidatingWebhookConfiguration
MutatingWebhook regv1.MutatingWebhookConfiguration
// Integrations
TrivyVulnerabilityReport trivy.VulnerabilityReport
TrivyConfigAuditReport trivy.ConfigAuditReport
}
type Result struct {

View File

@@ -0,0 +1,41 @@
package alex
import (
"github.com/k8sgpt-ai/k8sgpt/pkg/common"
)
// implement the IIterator interface
type Alex struct {
}
func NewAlex() *Alex {
return &Alex{}
}
func (a *Alex) Deploy(namespace string) error {
return nil
}
func (a *Alex) UnDeploy(namespace string) error {
return nil
}
func (a *Alex) AddAnalyzer(analyzers *map[string]common.IAnalyzer) {
(*analyzers)["Alex"] = NewAlexAnalyzer()
}
func (a *Alex) RemoveAnalyzer() error {
return nil
}
func (a *Alex) GetAnalyzerName() string {
return "alex"
}
func (a *Alex) IsActivate() bool {
return true
}

View File

@@ -0,0 +1,15 @@
package alex
import "github.com/k8sgpt-ai/k8sgpt/pkg/common"
type AlexAnalyzer struct {
}
func NewAlexAnalyzer() *AlexAnalyzer {
return &AlexAnalyzer{}
}
func (*AlexAnalyzer) Analyze(analysis common.Analyzer) ([]common.Result, error) {
return nil, nil
}

View File

@@ -15,9 +15,12 @@ package integration
import (
"errors"
"fmt"
"os"
"strings"
"github.com/fatih/color"
"github.com/k8sgpt-ai/k8sgpt/pkg/common"
"github.com/k8sgpt-ai/k8sgpt/pkg/integration/alex"
"github.com/k8sgpt-ai/k8sgpt/pkg/integration/trivy"
"github.com/k8sgpt-ai/k8sgpt/pkg/util"
"github.com/spf13/viper"
@@ -30,12 +33,10 @@ type IIntegration interface {
UnDeploy(namespace string) error
//
AddAnalyzer(*map[string]common.IAnalyzer)
// RemoveAnalyzer removes an analyzer from the cluster
RemoveAnalyzer() error
GetAnalyzerName() []string
// An integration must keep record of its deployed namespace (if not using --no-install)
GetNamespace() (string, error)
OwnsAnalyzer(string) bool
GetAnalyzerName() string
IsActivate() bool
}
@@ -45,6 +46,7 @@ type Integration struct {
var integrations = map[string]IIntegration{
"trivy": trivy.NewTrivy(),
"alex": alex.NewAlex(),
}
func NewIntegration() *Integration {
@@ -66,37 +68,30 @@ func (*Integration) Get(name string) (IIntegration, error) {
return integrations[name], nil
}
func (i *Integration) AnalyzerByIntegration(input string) (string, error) {
for _, name := range i.List() {
if integ, err := i.Get(name); err == nil {
if integ.OwnsAnalyzer(input) {
return name, nil
}
}
}
return "", errors.New("analyzerbyintegration: no matches found")
}
func (*Integration) Activate(name string, namespace string, activeFilters []string, skipInstall bool) error {
func (*Integration) Activate(name string, namespace string, activeFilters []string) error {
if _, ok := integrations[name]; !ok {
return errors.New("integration not found")
}
if !skipInstall {
if err := integrations[name].Deploy(namespace); err != nil {
return err
}
mergedFilters := append(activeFilters, integrations[name].GetAnalyzerName())
uniqueFilters, dupplicatedFilters := util.RemoveDuplicates(mergedFilters)
// Verify dupplicate
if len(dupplicatedFilters) != 0 {
color.Red("Integration already activated : %s", strings.Join(dupplicatedFilters, ", "))
os.Exit(1)
}
mergedFilters := activeFilters
mergedFilters = append(mergedFilters, integrations[name].GetAnalyzerName()...)
uniqueFilters, _ := util.RemoveDuplicates(mergedFilters)
viper.Set("active_filters", uniqueFilters)
if err := viper.WriteConfig(); err != nil {
return fmt.Errorf("error writing config file: %s", err.Error())
if err := integrations[name].Deploy(namespace); err != nil {
return err
}
if err := viper.WriteConfig(); err != nil {
color.Red("Error writing config file: %s", err.Error())
os.Exit(1)
}
return nil
@@ -109,14 +104,19 @@ func (*Integration) Deactivate(name string, namespace string) error {
activeFilters := viper.GetStringSlice("active_filters")
// Update filters and remove the specific filters for the integration
for _, filter := range integrations[name].GetAnalyzerName() {
for x, af := range activeFilters {
if af == filter {
activeFilters = append(activeFilters[:x], activeFilters[x+1:]...)
}
// Update filters
// This might be a bad idea, but we cannot reference analyzer here
foundFilter := false
for i, v := range activeFilters {
if v == integrations[name].GetAnalyzerName() {
foundFilter = true
activeFilters = append(activeFilters[:i], activeFilters[i+1:]...)
break
}
}
if !foundFilter {
color.Red("Ingregation %s does not exist in configuration file. Please use k8sgpt integration add.", name)
os.Exit(1)
}
if err := integrations[name].UnDeploy(namespace); err != nil {
@@ -126,8 +126,8 @@ func (*Integration) Deactivate(name string, namespace string) error {
viper.Set("active_filters", activeFilters)
if err := viper.WriteConfig(); err != nil {
return fmt.Errorf("error writing config file: %s", err.Error())
color.Red("Error writing config file: %s", err.Error())
os.Exit(1)
}
return nil

View File

@@ -15,7 +15,6 @@ package trivy
import (
"fmt"
"strings"
"github.com/aquasecurity/trivy-operator/pkg/apis/aquasecurity/v1alpha1"
"github.com/k8sgpt-ai/k8sgpt/pkg/common"
@@ -24,11 +23,10 @@ import (
)
type TrivyAnalyzer struct {
vulernabilityReportAnalysis bool
configAuditReportAnalysis bool
}
func (TrivyAnalyzer) analyzeVulnerabilityReports(a common.Analyzer) ([]common.Result, error) {
func (TrivyAnalyzer) Analyze(a common.Analyzer) ([]common.Result, error) {
// Get all trivy VulnerabilityReports
result := &v1alpha1.VulnerabilityReportList{}
@@ -42,7 +40,7 @@ func (TrivyAnalyzer) analyzeVulnerabilityReports(a common.Analyzer) ([]common.Re
if err != nil {
return nil, err
}
err = restClient.Get().Resource("vulnerabilityreports").Namespace(a.Namespace).Do(a.Context).Into(result)
err = restClient.Get().Resource("vulnerabilityreports").Do(a.Context).Into(result)
if err != nil {
return nil, err
}
@@ -55,7 +53,7 @@ func (TrivyAnalyzer) analyzeVulnerabilityReports(a common.Analyzer) ([]common.Re
// For each pod there may be multiple vulnerabilities
var failures []common.Failure
for _, vuln := range report.Report.Vulnerabilities {
if vuln.Severity == "CRITICAL" {
if vuln.Severity == "CRITICAL" || vuln.Severity == "HIGH" {
// get the vulnerability ID
// get the vulnerability description
failures = append(failures, common.Failure{
@@ -86,96 +84,4 @@ func (TrivyAnalyzer) analyzeVulnerabilityReports(a common.Analyzer) ([]common.Re
}
return a.Results, nil
}
func (t TrivyAnalyzer) analyzeConfigAuditReports(a common.Analyzer) ([]common.Result, error) {
// Get all trivy ConfigAuditReports
result := &v1alpha1.ConfigAuditReportList{}
config := a.Client.GetConfig()
// Add group version to sceheme
config.ContentConfig.GroupVersion = &v1alpha1.SchemeGroupVersion
config.UserAgent = rest.DefaultKubernetesUserAgent()
config.APIPath = "/apis"
restClient, err := rest.UnversionedRESTClientFor(config)
if err != nil {
return nil, err
}
err = restClient.Get().Resource("configauditreports").Namespace(a.Namespace).Do(a.Context).Into(result)
if err != nil {
return nil, err
}
// Find criticals and get CVE
var preAnalysis = map[string]common.PreAnalysis{}
for _, report := range result.Items {
// For each k8s resources there may be multiple checks
var failures []common.Failure
for _, check := range report.Report.Checks {
if check.Severity == "MEDIUM" || check.Severity == "HIGH" || check.Severity == "CRITICAL" {
failures = append(failures, common.Failure{
Text: fmt.Sprintf("Config issue with severity \"%s\" found: %s", check.Severity, strings.Join(check.Messages, "")),
Sensitive: []common.Sensitive{
{
Unmasked: report.Labels["trivy-operator.resource.name"],
Masked: util.MaskString(report.Labels["trivy-operator.resource.name"]),
},
{
Unmasked: report.Labels["trivy-operator.resource.namespace"],
Masked: util.MaskString(report.Labels["trivy-operator.resource.namespace"]),
},
},
})
}
}
if len(failures) > 0 {
preAnalysis[fmt.Sprintf("%s/%s", report.Labels["trivy-operator.resource.namespace"],
report.Labels["trivy-operator.resource.name"])] = common.PreAnalysis{
TrivyConfigAuditReport: report,
FailureDetails: failures,
}
}
}
for key, value := range preAnalysis {
var currentAnalysis = common.Result{
Kind: "ConfigAuditReport",
Name: key,
Error: value.FailureDetails,
}
parent, _ := util.GetParent(a.Client, value.TrivyConfigAuditReport.ObjectMeta)
currentAnalysis.ParentObject = parent
a.Results = append(a.Results, currentAnalysis)
}
return a.Results, nil
}
func (t TrivyAnalyzer) Analyze(a common.Analyzer) ([]common.Result, error) {
if t.vulernabilityReportAnalysis {
common := make([]common.Result, 0)
vresult, err := t.analyzeVulnerabilityReports(a)
if err != nil {
return nil, err
}
common = append(common, vresult...)
return common, nil
}
if t.configAuditReportAnalysis {
common := make([]common.Result, 0)
cresult, err := t.analyzeConfigAuditReports(a)
if err != nil {
return nil, err
}
common = append(common, cresult...)
return common, nil
}
return make([]common.Result, 0), nil
}

View File

@@ -16,8 +16,6 @@ package trivy
import (
"context"
"fmt"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"github.com/k8sgpt-ai/k8sgpt/pkg/common"
helmclient "github.com/mittwald/go-helm-client"
@@ -46,36 +44,10 @@ func NewTrivy() *Trivy {
}
}
func (t *Trivy) GetAnalyzerName() []string {
return []string{
"VulnerabilityReport",
"ConfigAuditReport",
}
func (t *Trivy) GetAnalyzerName() string {
return "VulnerabilityReport"
}
// This doesnt work
func (t *Trivy) GetNamespace() (string, error) {
releases, err := t.helm.ListDeployedReleases()
if err != nil {
return "", err
}
for _, rel := range releases {
if rel.Name == ReleaseName {
return rel.Namespace, nil
}
}
return "", status.Error(codes.NotFound, "trivy release not found")
}
func (t *Trivy) OwnsAnalyzer(analyzer string) bool {
for _, a := range t.GetAnalyzerName() {
if analyzer == a {
return true
}
}
return false
}
func (t *Trivy) Deploy(namespace string) error {
// Add the repository
@@ -83,6 +55,7 @@ func (t *Trivy) Deploy(namespace string) error {
Name: RepoShortName,
URL: Repo,
}
// Add a chart-repository to the client.
if err := t.helm.AddOrUpdateChartRepo(chartRepo); err != nil {
panic(err)
@@ -92,12 +65,9 @@ func (t *Trivy) Deploy(namespace string) error {
ReleaseName: ReleaseName,
ChartName: fmt.Sprintf("%s/%s", RepoShortName, ChartName),
Namespace: namespace,
//TODO: All of this should be configurable
UpgradeCRDs: true,
Wait: false,
Timeout: 300,
CreateNamespace: true,
UpgradeCRDs: true,
Wait: false,
Timeout: 300,
}
// Install a chart release.
@@ -137,11 +107,10 @@ func (t *Trivy) IsActivate() bool {
func (t *Trivy) AddAnalyzer(mergedMap *map[string]common.IAnalyzer) {
(*mergedMap)["VulnerabilityReport"] = &TrivyAnalyzer{
vulernabilityReportAnalysis: true,
}
(*mergedMap)["ConfigAuditReport"] = &TrivyAnalyzer{
configAuditReportAnalysis: true,
}
(*mergedMap)["VulnerabilityReport"] = &TrivyAnalyzer{}
}
func (t *Trivy) RemoveAnalyzer() error {
return nil
}

View File

@@ -37,7 +37,7 @@ func (c *Client) GetRestClient() rest.Interface {
func NewClient(kubecontext string, kubeconfig string) (*Client, error) {
var config *rest.Config
config, err := rest.InClusterConfig()
if kubeconfig != "" || err != nil {
if err != nil {
loadingRules := clientcmd.NewDefaultClientConfigLoadingRules()
if kubeconfig != "" {

View File

@@ -1,30 +0,0 @@
# serve
The serve commands allow you to run k8sgpt in a grpc server mode.
This would be enabled typically through `k8sgpt serve` and is how the in-cluster k8sgpt deployment functions when managed by the [k8sgpt-operator](https://github.com/k8sgpt-ai/k8sgpt-operator)
The grpc interface that is served is hosted on [buf](https://buf.build/k8sgpt-ai/schemas) and the repository for this is [here](https://github.com/k8sgpt-ai/schemas)
## grpcurl
A fantastic tool for local debugging and development is `grpcurl`
It allows you to form curl like requests that are http2
e.g.
```
grpcurl -plaintext -d '{"namespace": "k8sgpt", "explain" : "true"}' localhost:8080 schema.v1.ServerService/Analyze
```
```
grpcurl -plaintext localhost:8080 schema.v1.ServerService/ListIntegrations
{
"integrations": [
"trivy"
]
}
```
```
grpcurl -plaintext -d '{"integrations":{"trivy":{"enabled":"true","namespace":"default","skipInstall":"false"}}}' localhost:8080 schema.v1.ServerService/AddConfig
```

View File

@@ -2,47 +2,35 @@ package server
import (
"context"
"errors"
schemav1 "buf.build/gen/go/k8sgpt-ai/k8sgpt/protocolbuffers/go/schema/v1"
"github.com/k8sgpt-ai/k8sgpt/pkg/cache"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
func (h *handler) AddConfig(ctx context.Context, i *schemav1.AddConfigRequest) (*schemav1.AddConfigResponse, error,
) {
if i.Cache.BucketName == "" || i.Cache.Region == "" {
return nil, errors.New("BucketName & Region are required")
}
resp, err := h.syncIntegration(ctx, i)
err := cache.AddRemoteCache(i.Cache.BucketName, i.Cache.Region)
if err != nil {
return resp, err
return &schemav1.AddConfigResponse{}, err
}
if i.Cache != nil {
// We check if we have a mixed cache configuration
CacheConfigured := (i.Cache.Region == "" && i.Cache.BucketName == "") || (i.Cache.ContainerName == "" && i.Cache.StorageAccount == "")
if !CacheConfigured {
return resp, status.Error(codes.InvalidArgument, "mixed cache arguments")
}
cacheProvider := cache.NewCacheProvider(i.Cache.BucketName, i.Cache.Region, i.Cache.StorageAccount, i.Cache.ContainerName)
err := cache.AddRemoteCache(cacheProvider)
if err != nil {
return resp, err
}
}
return resp, nil
return &schemav1.AddConfigResponse{
Status: "Configuration updated.",
}, nil
}
func (h *handler) RemoveConfig(ctx context.Context, i *schemav1.RemoveConfigRequest) (*schemav1.RemoveConfigResponse, error,
) {
err := cache.RemoveRemoteCache()
err := cache.RemoveRemoteCache(i.Cache.BucketName)
if err != nil {
return &schemav1.RemoveConfigResponse{}, err
}
// Remove any integrations is a TBD as it would be nice to make this more granular
// Currently integrations can be removed in the AddConfig sync
return &schemav1.RemoveConfigResponse{
Status: "Successfully removed the remote cache",
}, nil

View File

@@ -1,144 +0,0 @@
package server
import (
schemav1 "buf.build/gen/go/k8sgpt-ai/k8sgpt/protocolbuffers/go/schema/v1"
"context"
"fmt"
"github.com/k8sgpt-ai/k8sgpt/pkg/analyzer"
"github.com/k8sgpt-ai/k8sgpt/pkg/integration"
"github.com/spf13/viper"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
const (
trivyName = "trivy"
)
// syncIntegration is aware of the following events
// A new integration added
// An integration removed from the Integration block
func (h *handler) syncIntegration(ctx context.Context,
i *schemav1.AddConfigRequest) (*schemav1.AddConfigResponse, error,
) {
response := &schemav1.AddConfigResponse{}
integrationProvider := integration.NewIntegration()
if i.Integrations == nil {
// If there are locally activate integrations, disable them
err := h.deactivateAllIntegrations(integrationProvider)
if err != nil {
return response, status.Error(codes.NotFound, "deactivation error")
}
return response, nil
}
coreFilters, _, _ := analyzer.ListFilters()
// Update filters
activeFilters := viper.GetStringSlice("active_filters")
if len(activeFilters) == 0 {
activeFilters = coreFilters
}
var err error = status.Error(codes.OK, "")
deactivateFunc := func(integrationRef integration.IIntegration) error {
namespace, err := integrationRef.GetNamespace()
if err != nil {
return err
}
err = integrationProvider.Deactivate(trivyName, namespace)
if err != nil {
return status.Error(codes.NotFound, "integration already deactivated")
}
return nil
}
integrationRef, err := integrationProvider.Get(trivyName)
if err != nil {
return response, status.Error(codes.NotFound, "provider get failure")
}
if i.Integrations.Trivy != nil {
switch i.Integrations.Trivy.Enabled {
case true:
if b, err := integrationProvider.IsActivate(trivyName); err != nil {
return response, status.Error(codes.Internal, "integration activation error")
} else {
if !b {
err := integrationProvider.Activate(trivyName, i.Integrations.Trivy.Namespace,
activeFilters, i.Integrations.Trivy.SkipInstall)
if err != nil {
return nil, err
}
} else {
return response, status.Error(codes.AlreadyExists, "integration already active")
}
}
case false:
err = deactivateFunc(integrationRef)
if err != nil {
return nil, err
}
// This break is included purely for static analysis to pass
}
} else {
// If Trivy has been removed, disable it
err = deactivateFunc(integrationRef)
if err != nil {
return nil, err
}
}
return response, err
}
func (*handler) ListIntegrations(ctx context.Context, req *schemav1.ListIntegrationsRequest) (*schemav1.ListIntegrationsResponse, error) {
integrationProvider := integration.NewIntegration()
// Update the requester with the status of Trivy
trivy, err := integrationProvider.Get(trivyName)
active := trivy.IsActivate()
var skipInstall bool
var namespace string = ""
if active {
namespace, err = trivy.GetNamespace()
if err != nil {
return nil, status.Error(codes.NotFound, "namespace not found")
}
if namespace == "" {
skipInstall = true
}
}
if err != nil {
return nil, status.Error(codes.NotFound, "trivy integration")
}
resp := &schemav1.ListIntegrationsResponse{
Trivy: &schemav1.Trivy{
Enabled: active,
Namespace: namespace,
SkipInstall: skipInstall,
},
}
return resp, nil
}
func (*handler) deactivateAllIntegrations(integrationProvider *integration.Integration) error {
integrations := integrationProvider.List()
for _, i := range integrations {
b, _ := integrationProvider.IsActivate(i)
if b {
in, err := integrationProvider.Get(i)
namespace, err := in.GetNamespace()
if err != nil {
return err
}
if err == nil {
if namespace != "" {
integrationProvider.Deactivate(i, namespace)
} else {
fmt.Printf("Skipping deactivation of %s, not installed\n", i)
}
} else {
return err
}
}
}
return nil
}

View File

@@ -15,12 +15,12 @@ package util
import (
"context"
"crypto/rand"
"crypto/sha256"
"encoding/base64"
"encoding/hex"
"errors"
"fmt"
"math/rand"
"os"
"regexp"
@@ -94,26 +94,6 @@ func GetParent(client *kubernetes.Client, meta metav1.ObjectMeta) (string, bool)
return GetParent(client, ds.ObjectMeta)
}
return "Ingress/" + ds.Name, false
case "MutatingWebhookConfiguration":
mw, err := client.GetClient().AdmissionregistrationV1().MutatingWebhookConfigurations().Get(context.Background(), owner.Name, metav1.GetOptions{})
if err != nil {
return "", false
}
if mw.OwnerReferences != nil {
return GetParent(client, mw.ObjectMeta)
}
return "MutatingWebhook/" + mw.Name, false
case "ValidatingWebhookConfiguration":
vw, err := client.GetClient().AdmissionregistrationV1().ValidatingWebhookConfigurations().Get(context.Background(), owner.Name, metav1.GetOptions{})
if err != nil {
return "", false
}
if vw.OwnerReferences != nil {
return GetParent(client, vw.ObjectMeta)
}
return "ValidatingWebhook/" + vw.Name, false
}
}
}
@@ -211,11 +191,3 @@ func EnsureDirExists(dir string) error {
return err
}
func MapToString(m map[string]string) string {
var result string
for k, v := range m {
result += fmt.Sprintf("%s=%s,", k, v)
}
return result[:len(result)-1]
}

View File

@@ -12,11 +12,6 @@
"gomodMassage"
],
"packageRules": [
{
"description": "Exclude retracted cohere-go versions: https://github.com/renovatebot/renovate/issues/13012",
"matchPackageNames": ["github.com/cohere-ai/cohere-go"],
"allowedVersions": "<1"
},
{
"matchUpdateTypes": ["minor", "patch"],
"matchCurrentVersion": "!/^0/",
@@ -49,4 +44,4 @@
]
}
]
}
}