mirror of
https://github.com/k8sgpt-ai/k8sgpt.git
synced 2026-03-19 11:33:08 +00:00
Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9f0cb6240e | ||
|
|
26db0f6941 | ||
|
|
2acab541bc | ||
|
|
53a19bb04d | ||
|
|
c8f3c946b0 | ||
|
|
b061566404 | ||
|
|
be061da5b6 | ||
|
|
5f548421c7 | ||
|
|
0afd52844b | ||
|
|
f95c1e1d8c | ||
|
|
3fc0d45823 | ||
|
|
cf633b606d | ||
|
|
ab63bd0dd1 | ||
|
|
3e05eb2af2 | ||
|
|
548039ebe6 | ||
|
|
0d5b8ad027 | ||
|
|
0f910e497a | ||
|
|
172c2df6c5 | ||
|
|
2eab0c544f | ||
|
|
f4765bed1b | ||
|
|
14ba8d5550 | ||
|
|
bf49a51c62 | ||
|
|
86c7e81e18 | ||
|
|
cdc7bb1272 | ||
|
|
fe683b71b8 | ||
|
|
cad2b38d03 | ||
|
|
01b2826475 | ||
|
|
4f24368758 | ||
|
|
27b8916f29 | ||
|
|
fe73633273 |
2
.github/workflows/release.yaml
vendored
2
.github/workflows/release.yaml
vendored
@@ -25,7 +25,7 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 # v3
|
||||
|
||||
- uses: google-github-actions/release-please-action@e0b9d1885d92e9a93d5ce8656de60e3b806e542c # v3
|
||||
- uses: google-github-actions/release-please-action@ee9822ec2c397e8a364d634464339ac43a06e042 # v3
|
||||
id: release
|
||||
with:
|
||||
command: manifest
|
||||
|
||||
@@ -1 +1 @@
|
||||
{".":"0.1.2"}
|
||||
{".":"0.1.4"}
|
||||
48
CHANGELOG.md
48
CHANGELOG.md
@@ -1,5 +1,53 @@
|
||||
# Changelog
|
||||
|
||||
## [0.1.4](https://github.com/k8sgpt-ai/k8sgpt/compare/v0.1.3...v0.1.4) (2023-03-30)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add Ingress class validation ([#154](https://github.com/k8sgpt-ai/k8sgpt/issues/154)) ([b061566](https://github.com/k8sgpt-ai/k8sgpt/commit/b061566404ef80288ca29add2d401574109d44c0))
|
||||
* output selected backend ([#153](https://github.com/k8sgpt-ai/k8sgpt/issues/153)) ([be061da](https://github.com/k8sgpt-ai/k8sgpt/commit/be061da5b65045938acd70ad2eb2d21b87d2d6bf))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* now supports different kubeconfig and kubectx ([c8f3c94](https://github.com/k8sgpt-ai/k8sgpt/commit/c8f3c946b00c00cd185961a4fa777806da94014e))
|
||||
|
||||
|
||||
### Refactoring
|
||||
|
||||
* removed sample flag ([0afd528](https://github.com/k8sgpt-ai/k8sgpt/commit/0afd52844b96579391f77698bf0555145b6d2be8))
|
||||
|
||||
## [0.1.3](https://github.com/k8sgpt-ai/k8sgpt/compare/v0.1.2...v0.1.3) (2023-03-30)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add secret validation to ingress analyzer ([#141](https://github.com/k8sgpt-ai/k8sgpt/issues/141)) ([86c7e81](https://github.com/k8sgpt-ai/k8sgpt/commit/86c7e81e18db02ebcbfe35d470682c982871375f))
|
||||
* bugfix for output ([2eab0c5](https://github.com/k8sgpt-ai/k8sgpt/commit/2eab0c544fbb6026f6aea79b08d8f29c061acf2e))
|
||||
* CODE_OF_CONDUCT.md ([#129](https://github.com/k8sgpt-ai/k8sgpt/issues/129)) ([fe73633](https://github.com/k8sgpt-ai/k8sgpt/commit/fe73633273c5c1f4188bca48471283535967d5aa))
|
||||
* create-security.md ([27b8916](https://github.com/k8sgpt-ai/k8sgpt/commit/27b8916f297570907437686c6d958636fb249d50))
|
||||
* improvement to analysis speed ([548039e](https://github.com/k8sgpt-ai/k8sgpt/commit/548039ebe62bb609c1aa288e5e49845850fd2dd8))
|
||||
* init ingress analyzer ([#138](https://github.com/k8sgpt-ai/k8sgpt/issues/138)) ([fe683b7](https://github.com/k8sgpt-ai/k8sgpt/commit/fe683b71b84fe82459b0ffe366b4dcfa1c978cfe))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* add Ingress in GetParent switch case ([14ba8d5](https://github.com/k8sgpt-ai/k8sgpt/commit/14ba8d555005f31fc2201cb8b61653093c19b8a7))
|
||||
* bugfix for output ([#148](https://github.com/k8sgpt-ai/k8sgpt/issues/148)) ([172c2df](https://github.com/k8sgpt-ai/k8sgpt/commit/172c2df6c55f5fddbfec7f8526be5f2323d1b900))
|
||||
* Change ObjectMeta value in Ingress analyser. ([bf49a51](https://github.com/k8sgpt-ai/k8sgpt/commit/bf49a51c62af450cff51a590547ef30989bd2e93))
|
||||
* typo in description of the filter flag in analyze command ([#147](https://github.com/k8sgpt-ai/k8sgpt/issues/147)) ([f4765be](https://github.com/k8sgpt-ai/k8sgpt/commit/f4765bed1b1ad121a81b35878fdb866354b5e34a))
|
||||
|
||||
|
||||
### Other
|
||||
|
||||
* **deps:** update google-github-actions/release-please-action digest to ee9822e ([#132](https://github.com/k8sgpt-ai/k8sgpt/issues/132)) ([01b2826](https://github.com/k8sgpt-ai/k8sgpt/commit/01b282647512a4eaebd42ab5847b5534de148d14))
|
||||
|
||||
|
||||
### Docs
|
||||
|
||||
* add new slack link ([#134](https://github.com/k8sgpt-ai/k8sgpt/issues/134)) ([#135](https://github.com/k8sgpt-ai/k8sgpt/issues/135)) ([cad2b38](https://github.com/k8sgpt-ai/k8sgpt/commit/cad2b38d037658495024ec0166ebd3e936f65c2e))
|
||||
|
||||
## [0.1.2](https://github.com/k8sgpt-ai/k8sgpt/compare/v0.1.1...v0.1.2) (2023-03-28)
|
||||
|
||||
|
||||
|
||||
128
CODE_OF_CONDUCT.md
Normal file
128
CODE_OF_CONDUCT.md
Normal file
@@ -0,0 +1,128 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation in our
|
||||
community a harassment-free experience for everyone, regardless of age, body
|
||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||
identity and expression, level of experience, education, socio-economic status,
|
||||
nationality, personal appearance, race, religion, or sexual identity
|
||||
and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||
diverse, inclusive, and healthy community.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our
|
||||
community include:
|
||||
|
||||
* Demonstrating empathy and kindness toward other people
|
||||
* Being respectful of differing opinions, viewpoints, and experiences
|
||||
* Giving and gracefully accepting constructive feedback
|
||||
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
and learning from the experience
|
||||
* Focusing on what is best not just for us as individuals, but for the
|
||||
overall community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
* The use of sexualized language or imagery, and sexual attention or
|
||||
advances of any kind
|
||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or email
|
||||
address, without their explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Enforcement Responsibilities
|
||||
|
||||
Community leaders are responsible for clarifying and enforcing our standards of
|
||||
acceptable behavior and will take appropriate and fair corrective action in
|
||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||
or harmful.
|
||||
|
||||
Community leaders have the right and responsibility to remove, edit, or reject
|
||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||
decisions when appropriate.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces, and also applies when
|
||||
an individual is officially representing the community in public spaces.
|
||||
Examples of representing our community include using an official e-mail address,
|
||||
posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement at
|
||||
contact@k8sgpt.ai.
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
reporter of any incident.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining
|
||||
the consequences for any action they deem in violation of this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||
unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing
|
||||
clarity around the nature of the violation and an explanation of why the
|
||||
behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series
|
||||
of actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No
|
||||
interaction with the people involved, including unsolicited interaction with
|
||||
those enforcing the Code of Conduct, for a specified period of time. This
|
||||
includes avoiding interactions in community spaces as well as external channels
|
||||
like social media. Violating these terms may lead to a temporary or
|
||||
permanent ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards, including
|
||||
sustained inappropriate behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public
|
||||
communication with the community for a specified period of time. No public or
|
||||
private interaction with the people involved, including unsolicited interaction
|
||||
with those enforcing the Code of Conduct, is allowed during this period.
|
||||
Violating these terms may lead to a permanent ban.
|
||||
|
||||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community
|
||||
standards, including sustained inappropriate behavior, harassment of an
|
||||
individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within
|
||||
the community.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
version 2.0, available at
|
||||
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||
|
||||
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
||||
enforcement ladder](https://github.com/mozilla/diversity).
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
https://www.contributor-covenant.org/faq. Translations are available at
|
||||
https://www.contributor-covenant.org/translations.
|
||||
@@ -17,8 +17,8 @@ brew install k8sgpt
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Failing Installation on WSL (missing gcc)</summary>
|
||||
When installing Homebrew on WSL, you may encounter the following error:
|
||||
<summary>Failing Installation on WSL or Linux (missing gcc)</summary>
|
||||
When installing Homebrew on WSL or Linux, you may encounter the following error:
|
||||
|
||||
```
|
||||
==> Installing k8sgpt from k8sgpt-ai/k8sgpt Error: The following formula cannot be installed from bottle and must be
|
||||
@@ -64,6 +64,7 @@ you will be able to write your own analyzers.
|
||||
- [x] rsAnalyzer
|
||||
- [x] serviceAnalyzer
|
||||
- [x] eventAnalyzer
|
||||
- [x] ingressAnalyzer
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -138,4 +139,4 @@ the root cause of an issue.
|
||||
|
||||
Please read our [contributing guide](./CONTRIBUTING.md).
|
||||
## Community
|
||||
* Find us on [Slack](https://cloud-native.slack.com/channels/k8sgpt-ai)
|
||||
* Find us on [Slack](https://k8sgpt.slack.com/)
|
||||
|
||||
11
SECURITY.md
Normal file
11
SECURITY.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
We currently support the latest release for security patching and will deploy forward releases.
|
||||
|
||||
For example if there is a vulnerability in release `0.1.0` we will fix that release in version `0.1.1-fix` or `0.1.1`
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
If you are aware of a vulnverability please feel free to disclose it responsibly to contact@k8sgpt.ai or to one of our maintainers in our Slack community.
|
||||
@@ -77,23 +77,11 @@ var AnalyzeCmd = &cobra.Command{
|
||||
}
|
||||
|
||||
var analysisResults *[]analyzer.Analysis = &[]analyzer.Analysis{}
|
||||
if err := analyzer.RunAnalysis(ctx, config, client,
|
||||
if err := analyzer.RunAnalysis(ctx, filters, config, client,
|
||||
aiClient, analysisResults); err != nil {
|
||||
color.Red("Error: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
// Removed filtered results from slice
|
||||
if len(filters) > 0 {
|
||||
var filteredResults []analyzer.Analysis
|
||||
for _, analysis := range *analysisResults {
|
||||
for _, filter := range filters {
|
||||
if strings.Contains(analysis.Kind, filter) {
|
||||
filteredResults = append(filteredResults, analysis)
|
||||
}
|
||||
}
|
||||
}
|
||||
analysisResults = &filteredResults
|
||||
}
|
||||
|
||||
var bar *progressbar.ProgressBar
|
||||
if len(*analysisResults) > 0 {
|
||||
@@ -139,9 +127,12 @@ var AnalyzeCmd = &cobra.Command{
|
||||
}
|
||||
fmt.Println(string(j))
|
||||
default:
|
||||
fmt.Printf("%s %s(%s): %s \n%s\n", color.CyanString("%d", n),
|
||||
color.YellowString(analysis.Name), color.CyanString(analysis.ParentObject),
|
||||
color.RedString(analysis.Error[0]), color.GreenString(analysis.Details))
|
||||
fmt.Printf("%s %s(%s)\n", color.CyanString("%d", n),
|
||||
color.YellowString(analysis.Name), color.CyanString(analysis.ParentObject))
|
||||
for _, err := range analysis.Error {
|
||||
fmt.Printf("- %s %s\n", color.RedString("Error:"), color.RedString(err))
|
||||
}
|
||||
color.GreenString(analysis.Details)
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -154,7 +145,7 @@ func init() {
|
||||
// no cache flag
|
||||
AnalyzeCmd.Flags().BoolVarP(&nocache, "no-cache", "c", false, "Do not use cached data")
|
||||
// array of strings flag
|
||||
AnalyzeCmd.Flags().StringSliceVarP(&filters, "filter", "f", []string{}, "Filter for these analzyers (e.g. Pod,PersistentVolumeClaim,Service,ReplicaSet)")
|
||||
AnalyzeCmd.Flags().StringSliceVarP(&filters, "filter", "f", []string{}, "Filter for these analyzers (e.g. Pod, PersistentVolumeClaim, Service, ReplicaSet)")
|
||||
// explain flag
|
||||
AnalyzeCmd.Flags().BoolVarP(&explain, "explain", "e", false, "Explain the problem to me")
|
||||
// add flag for backend
|
||||
|
||||
@@ -35,6 +35,7 @@ var AuthCmd = &cobra.Command{
|
||||
// override the default backend if a flag is provided
|
||||
if backend != "" {
|
||||
backendType = backend
|
||||
color.Green("Using %s as backend AI provider", backendType)
|
||||
}
|
||||
|
||||
fmt.Printf("Enter %s Key: ", backendType)
|
||||
|
||||
29
cmd/root.go
29
cmd/root.go
@@ -1,8 +1,11 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/k8sgpt-ai/k8sgpt/cmd/generate"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/k8sgpt-ai/k8sgpt/cmd/generate"
|
||||
"k8s.io/client-go/util/homedir"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/k8sgpt-ai/k8sgpt/cmd/analyze"
|
||||
@@ -13,10 +16,10 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
cfgFile string
|
||||
masterURL string
|
||||
kubeconfig string
|
||||
version string
|
||||
cfgFile string
|
||||
kubecontext string
|
||||
kubeconfig string
|
||||
version string
|
||||
)
|
||||
|
||||
// rootCmd represents the base command when called without any subcommands
|
||||
@@ -42,23 +45,25 @@ func Execute(v string) {
|
||||
func init() {
|
||||
cobra.OnInitialize(initConfig)
|
||||
|
||||
// Here you will define your flags and configuration settings.
|
||||
// Cobra supports persistent flags, which, if defined here,
|
||||
// will be global for your application.
|
||||
var kubeconfigPath string
|
||||
if home := homedir.HomeDir(); home != "" {
|
||||
kubeconfigPath = filepath.Join(home, ".kube", "config")
|
||||
}
|
||||
rootCmd.AddCommand(auth.AuthCmd)
|
||||
rootCmd.AddCommand(analyze.AnalyzeCmd)
|
||||
rootCmd.AddCommand(generate.GenerateCmd)
|
||||
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.k8sgpt.yaml)")
|
||||
rootCmd.PersistentFlags().StringVar(&masterURL, "master", "", "The address of the Kubernetes API server. Overrides any value in kubeconfig. Only required if out-of-cluster.")
|
||||
rootCmd.PersistentFlags().StringVar(&kubeconfig, "kubeconfig", "", "Path to a kubeconfig. Only required if out-of-cluster.")
|
||||
rootCmd.PersistentFlags().StringVar(&kubecontext, "kubecontext", "", "Kubernetes context to use. Only required if out-of-cluster.")
|
||||
rootCmd.PersistentFlags().StringVar(&kubeconfig, "kubeconfig", kubeconfigPath, "Path to a kubeconfig. Only required if out-of-cluster.")
|
||||
// Cobra also supports local flags, which will only run
|
||||
// when this action is called directly.
|
||||
rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
|
||||
// rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
|
||||
|
||||
//Initialise the kubeconfig
|
||||
kubernetesClient, err := kubernetes.NewClient(masterURL, kubeconfig)
|
||||
kubernetesClient, err := kubernetes.NewClient(kubecontext, kubeconfig)
|
||||
if err != nil {
|
||||
color.Red("Error initialising kubernetes client: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
viper.Set("kubernetesClient", kubernetesClient)
|
||||
|
||||
@@ -3,6 +3,7 @@ package analyzer
|
||||
import (
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
networkingv1 "k8s.io/api/networking/v1"
|
||||
)
|
||||
|
||||
type AnalysisConfiguration struct {
|
||||
@@ -17,6 +18,7 @@ type PreAnalysis struct {
|
||||
ReplicaSet appsv1.ReplicaSet
|
||||
PersistentVolumeClaim v1.PersistentVolumeClaim
|
||||
Endpoint v1.Endpoints
|
||||
Ingress networkingv1.Ingress
|
||||
}
|
||||
|
||||
type Analysis struct {
|
||||
|
||||
@@ -11,28 +11,35 @@ import (
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func RunAnalysis(ctx context.Context, config *AnalysisConfiguration,
|
||||
var analyzerMap = map[string]func(ctx context.Context, config *AnalysisConfiguration,
|
||||
client *kubernetes.Client, aiClient ai.IAI, analysisResults *[]Analysis) error{
|
||||
"Pod": AnalyzePod,
|
||||
"ReplicaSet": AnalyzeReplicaSet,
|
||||
"PersistentVolumeClaim": AnalyzePersistentVolumeClaim,
|
||||
"Service": AnalyzeEndpoints,
|
||||
"Ingress": AnalyzeIngress,
|
||||
}
|
||||
|
||||
func RunAnalysis(ctx context.Context, filters []string, config *AnalysisConfiguration,
|
||||
client *kubernetes.Client,
|
||||
aiClient ai.IAI, analysisResults *[]Analysis) error {
|
||||
|
||||
err := AnalyzePod(ctx, config, client, aiClient, analysisResults)
|
||||
if err != nil {
|
||||
return err
|
||||
// if there are no filters selected then run all of them
|
||||
if len(filters) == 0 {
|
||||
for _, analyzer := range analyzerMap {
|
||||
if err := analyzer(ctx, config, client, aiClient, analysisResults); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
err = AnalyzeReplicaSet(ctx, config, client, aiClient, analysisResults)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = AnalyzePersistentVolumeClaim(ctx, config, client, aiClient, analysisResults)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = AnalyzeEndpoints(ctx, config, client, aiClient, analysisResults)
|
||||
if err != nil {
|
||||
return err
|
||||
for _, filter := range filters {
|
||||
if analyzer, ok := analyzerMap[filter]; ok {
|
||||
if err := analyzer(ctx, config, client, aiClient, analysisResults); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
84
pkg/analyzer/ingressAnalyzer.go
Normal file
84
pkg/analyzer/ingressAnalyzer.go
Normal file
@@ -0,0 +1,84 @@
|
||||
package analyzer
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/k8sgpt-ai/k8sgpt/pkg/ai"
|
||||
"github.com/k8sgpt-ai/k8sgpt/pkg/kubernetes"
|
||||
"github.com/k8sgpt-ai/k8sgpt/pkg/util"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
func AnalyzeIngress(ctx context.Context, config *AnalysisConfiguration, client *kubernetes.Client, aiClient ai.IAI,
|
||||
analysisResults *[]Analysis) error {
|
||||
|
||||
list, err := client.GetClient().NetworkingV1().Ingresses(config.Namespace).List(ctx, metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var preAnalysis = map[string]PreAnalysis{}
|
||||
|
||||
for _, ing := range list.Items {
|
||||
var failures []string
|
||||
|
||||
// get ingressClassName
|
||||
ingressClassName := ing.Spec.IngressClassName
|
||||
if ingressClassName == nil {
|
||||
ingClassValue := ing.Annotations["kubernetes.io/ingress.class"]
|
||||
if ingClassValue == "" {
|
||||
failures = append(failures, fmt.Sprintf("Ingress %s/%s does not specify an Ingress class.", ing.Namespace, ing.Name))
|
||||
} else {
|
||||
ingressClassName = &ingClassValue
|
||||
}
|
||||
}
|
||||
|
||||
// check if ingressclass exist
|
||||
if ingressClassName != nil {
|
||||
_, err := client.GetClient().NetworkingV1().IngressClasses().Get(ctx, *ingressClassName, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
failures = append(failures, fmt.Sprintf("Ingress uses the ingress class %s which does not exist.", *ingressClassName))
|
||||
}
|
||||
}
|
||||
|
||||
// loop over rules
|
||||
for _, rule := range ing.Spec.Rules {
|
||||
// loop over paths
|
||||
for _, path := range rule.HTTP.Paths {
|
||||
_, err := client.GetClient().CoreV1().Services(ing.Namespace).Get(ctx, path.Backend.Service.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
failures = append(failures, fmt.Sprintf("Ingress uses the service %s/%s which does not exist.", ing.Namespace, path.Backend.Service.Name))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, tls := range ing.Spec.TLS {
|
||||
_, err := client.GetClient().CoreV1().Secrets(ing.Namespace).Get(ctx, tls.SecretName, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
failures = append(failures, fmt.Sprintf("Ingress uses the secret %s/%s as a TLS certificate which does not exist.", ing.Namespace, tls.SecretName))
|
||||
}
|
||||
}
|
||||
if len(failures) > 0 {
|
||||
preAnalysis[fmt.Sprintf("%s/%s", ing.Namespace, ing.Name)] = PreAnalysis{
|
||||
Ingress: ing,
|
||||
FailureDetails: failures,
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for key, value := range preAnalysis {
|
||||
var currentAnalysis = Analysis{
|
||||
Kind: "Ingress",
|
||||
Name: key,
|
||||
Error: value.FailureDetails,
|
||||
}
|
||||
|
||||
parent, _ := util.GetParent(client, value.Ingress.ObjectMeta)
|
||||
currentAnalysis.ParentObject = parent
|
||||
*analysisResults = append(*analysisResults, currentAnalysis)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -2,7 +2,6 @@ package kubernetes
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
)
|
||||
|
||||
@@ -14,21 +13,23 @@ func (c *Client) GetClient() *kubernetes.Clientset {
|
||||
return c.client
|
||||
}
|
||||
|
||||
func NewClient(masterURL string, kubeconfig string) (*Client, error) {
|
||||
func NewClient(kubecontext string, kubeconfig string) (*Client, error) {
|
||||
|
||||
config, err := rest.InClusterConfig()
|
||||
if err != nil {
|
||||
kubeconfig :=
|
||||
clientcmd.NewDefaultClientConfigLoadingRules().GetDefaultFilename()
|
||||
config, err = clientcmd.BuildConfigFromFlags(masterURL, kubeconfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
clientSet, err := kubernetes.NewForConfig(config)
|
||||
config := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
|
||||
&clientcmd.ClientConfigLoadingRules{ExplicitPath: kubeconfig},
|
||||
&clientcmd.ConfigOverrides{
|
||||
CurrentContext: kubecontext,
|
||||
})
|
||||
// create the clientset
|
||||
c, err := config.ClientConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
clientSet, err := kubernetes.NewForConfig(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Client{
|
||||
client: clientSet,
|
||||
}, nil
|
||||
|
||||
@@ -50,6 +50,16 @@ func GetParent(client *kubernetes.Client, meta metav1.ObjectMeta) (string, bool)
|
||||
return GetParent(client, ds.ObjectMeta)
|
||||
}
|
||||
return "DaemonSet/" + ds.Name, false
|
||||
|
||||
case "Ingress":
|
||||
ds, err := client.GetClient().NetworkingV1().Ingresses(meta.Namespace).Get(context.Background(), owner.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return "", false
|
||||
}
|
||||
if ds.OwnerReferences != nil {
|
||||
return GetParent(client, ds.ObjectMeta)
|
||||
}
|
||||
return "Ingress/" + ds.Name, false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user