Compare commits

...
144 Commits
Author SHA1 Message Date
dependabot[bot]andlnx01 d83d8ebfc6 chore(deps): bump the security group with 5 updates (#1592)
Bumps the security group with 5 updates:

| Package | From | To |
| --- | --- | --- |
| [github.com/containers/image/v5](https://github.com/containers/image) | `5.32.0` | `5.32.1` |
| [sigs.k8s.io/controller-runtime](https://github.com/kubernetes-sigs/controller-runtime) | `0.18.4` | `0.18.5` |
| [golang.org/x/net](https://github.com/golang/net) | `0.27.0` | `0.28.0` |
| [golang.org/x/sys](https://github.com/golang/sys) | `0.23.0` | `0.24.0` |
| [golang.org/x/text](https://github.com/golang/text) | `0.16.0` | `0.17.0` |


Updates `github.com/containers/image/v5` from 5.32.0 to 5.32.1
- [Release notes](https://github.com/containers/image/releases)
- [Commits](https://github.com/containers/image/compare/v5.32.0...v5.32.1)

Updates `sigs.k8s.io/controller-runtime` from 0.18.4 to 0.18.5
- [Release notes](https://github.com/kubernetes-sigs/controller-runtime/releases)
- [Changelog](https://github.com/kubernetes-sigs/controller-runtime/blob/main/RELEASE.md)
- [Commits](https://github.com/kubernetes-sigs/controller-runtime/compare/v0.18.4...v0.18.5)

Updates `golang.org/x/net` from 0.27.0 to 0.28.0
- [Commits](https://github.com/golang/net/compare/v0.27.0...v0.28.0)

Updates `golang.org/x/sys` from 0.23.0 to 0.24.0
- [Commits](https://github.com/golang/sys/compare/v0.23.0...v0.24.0)

Updates `golang.org/x/text` from 0.16.0 to 0.17.0
- [Release notes](https://github.com/golang/text/releases)
- [Commits](https://github.com/golang/text/compare/v0.16.0...v0.17.0)

---
updated-dependencies:
- dependency-name: github.com/containers/image/v5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: sigs.k8s.io/controller-runtime
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: golang.org/x/sys
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: golang.org/x/text
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-13 00:21:04 +00:00
Gerard Nguyen 47656a8e6f feat: etcd collector (#1589)
* new schema for etcd collector

* add placeholder

* wip

* get supported distribution

* add exec implementation

* wait for etcd pod to be ready

* misc

* update k0s etcd certs path

* fix unit tests

* address code reviews

* update from code review

* add etcdctl version
2024-08-13 08:42:26 +10:00
Gerard Nguyen 60263caf78 feat: [sc-108732] Can't add annotations in pods executed with the runPod collector (#1590)
add new field annotations for run pod collector
2024-08-08 10:13:36 +10:00
dependabot[bot]andlnx01 87cedca468 chore(deps): bump the security group with 3 updates (#1591)
Bumps the security group with 3 updates: [golang.org/x/mod](https://github.com/golang/mod), [golang.org/x/sync](https://github.com/golang/sync) and [golang.org/x/sys](https://github.com/golang/sys).


Updates `golang.org/x/mod` from 0.19.0 to 0.20.0
- [Commits](https://github.com/golang/mod/compare/v0.19.0...v0.20.0)

Updates `golang.org/x/sync` from 0.7.0 to 0.8.0
- [Commits](https://github.com/golang/sync/compare/v0.7.0...v0.8.0)

Updates `golang.org/x/sys` from 0.22.0 to 0.23.0
- [Commits](https://github.com/golang/sys/compare/v0.22.0...v0.23.0)

---
updated-dependencies:
- dependency-name: golang.org/x/mod
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: golang.org/x/sync
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: golang.org/x/sys
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-06 00:20:09 +00:00
dependabot[bot]andlnx01 16237e4459 chore(deps): bump the security group with 4 updates (#1588)
Bumps the security group with 4 updates: [github.com/cilium/ebpf](https://github.com/cilium/ebpf), [github.com/containers/image/v5](https://github.com/containers/image), [golang.org/x/exp](https://github.com/golang/exp) and [oras.land/oras-go](https://github.com/oras-project/oras-go).


Updates `github.com/cilium/ebpf` from 0.11.0 to 0.16.0
- [Release notes](https://github.com/cilium/ebpf/releases)
- [Commits](https://github.com/cilium/ebpf/compare/v0.11.0...v0.16.0)

Updates `github.com/containers/image/v5` from 5.31.1 to 5.32.0
- [Release notes](https://github.com/containers/image/releases)
- [Commits](https://github.com/containers/image/compare/v5.31.1...v5.32.0)

Updates `golang.org/x/exp` from 0.0.0-20240506185415-9bf2ced13842 to 0.0.0-20240613232115-7f521ea00fb8
- [Commits](https://github.com/golang/exp/commits)

Updates `oras.land/oras-go` from 1.2.5 to 1.2.6
- [Release notes](https://github.com/oras-project/oras-go/releases)
- [Commits](https://github.com/oras-project/oras-go/compare/v1.2.5...v1.2.6)

---
updated-dependencies:
- dependency-name: github.com/cilium/ebpf
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: github.com/containers/image/v5
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: golang.org/x/exp
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: oras.land/oras-go
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-30 00:20:17 +00:00
Gerard Nguyen a57171a918 feat: [sc-108689] troubleshoot: journald collector (#1586)
* add schema for Journald Host Collector

* implement journald host collector

* update host collector

* add --no-pager
2024-07-29 09:44:43 +10:00
Evans Mungai 01d5804977 feat: cgroups host collector (#1581)
Linux control groups host collector that detects whether the specified mountPoint is a cgroup filesystem and what version it is. The collector also collects information of the configured cgroup controllers.

Signed-off-by: Evans Mungai <evans@replicated.com>
2024-07-24 16:46:04 +01:00
22cc02cd29 chore(deps): bump github.com/distribution/distribution/v3 from 3.0.0-alpha.1 to 3.0.0-beta.1 (#1576)
* chore(deps): bump github.com/distribution/distribution/v3

Bumps [github.com/distribution/distribution/v3](https://github.com/distribution/distribution) from 3.0.0-alpha.1 to 3.0.0-beta.1.
- [Release notes](https://github.com/distribution/distribution/releases)
- [Commits](https://github.com/distribution/distribution/compare/v3.0.0-alpha.1...v3.0.0-beta.1)

---
updated-dependencies:
- dependency-name: github.com/distribution/distribution/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Run go mod tidy

Signed-off-by: Evans Mungai <evans@replicated.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Evans Mungai <evans@replicated.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Evans Mungai <evans@replicated.com>
2024-07-24 16:10:24 +01:00
Evans Mungai 1444c01725 feat: json compare host analyser (#1582)
* feat: json compore host analyser

Signed-off-by: Evans Mungai <evans@replicated.com>

* Add missing json compare host analyser file

Signed-off-by: Evans Mungai <evans@replicated.com>

* Generate schemas

Signed-off-by: Evans Mungai <evans@replicated.com>

* Fix failing tests

Signed-off-by: Evans Mungai <evans@replicated.com>

* Ensure json compare analyser always has a title

Signed-off-by: Evans Mungai <evans@replicated.com>

---------

Signed-off-by: Evans Mungai <evans@replicated.com>
2024-07-24 14:27:20 +01:00
Evans Mungai 0020c1129e feat: Allow checking kernel versions only in host os analyzer (#1585)
* Allow checking kernel versions only in host os analyzer

Signed-off-by: Evans Mungai <evans@replicated.com>

* Minor fix in logic

Signed-off-by: Evans Mungai <evans@replicated.com>

* Fix formatting

Signed-off-by: Evans Mungai <evans@replicated.com>

---------

Signed-off-by: Evans Mungai <evans@replicated.com>
2024-07-24 07:04:59 +01:00
dependabot[bot]andlnx01 1788376472 chore(deps): bump the security group with 9 updates (#1583)
Bumps the security group with 9 updates:

| Package | From | To |
| --- | --- | --- |
| [k8s.io/api](https://github.com/kubernetes/api) | `0.30.2` | `0.30.3` |
| [k8s.io/apiextensions-apiserver](https://github.com/kubernetes/apiextensions-apiserver) | `0.30.2` | `0.30.3` |
| [k8s.io/apimachinery](https://github.com/kubernetes/apimachinery) | `0.30.2` | `0.30.3` |
| [k8s.io/apiserver](https://github.com/kubernetes/apiserver) | `0.30.2` | `0.30.3` |
| [k8s.io/cli-runtime](https://github.com/kubernetes/cli-runtime) | `0.30.2` | `0.30.3` |
| [k8s.io/client-go](https://github.com/kubernetes/client-go) | `0.30.2` | `0.30.3` |
| [helm.sh/helm/v3](https://github.com/helm/helm) | `3.15.2` | `3.15.3` |
| [k8s.io/kubelet](https://github.com/kubernetes/kubelet) | `0.30.2` | `0.30.3` |
| [k8s.io/metrics](https://github.com/kubernetes/metrics) | `0.30.2` | `0.30.3` |


Updates `k8s.io/api` from 0.30.2 to 0.30.3
- [Commits](https://github.com/kubernetes/api/compare/v0.30.2...v0.30.3)

Updates `k8s.io/apiextensions-apiserver` from 0.30.2 to 0.30.3
- [Release notes](https://github.com/kubernetes/apiextensions-apiserver/releases)
- [Commits](https://github.com/kubernetes/apiextensions-apiserver/compare/v0.30.2...v0.30.3)

Updates `k8s.io/apimachinery` from 0.30.2 to 0.30.3
- [Commits](https://github.com/kubernetes/apimachinery/compare/v0.30.2...v0.30.3)

Updates `k8s.io/apiserver` from 0.30.2 to 0.30.3
- [Commits](https://github.com/kubernetes/apiserver/compare/v0.30.2...v0.30.3)

Updates `k8s.io/cli-runtime` from 0.30.2 to 0.30.3
- [Commits](https://github.com/kubernetes/cli-runtime/compare/v0.30.2...v0.30.3)

Updates `k8s.io/client-go` from 0.30.2 to 0.30.3
- [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kubernetes/client-go/compare/v0.30.2...v0.30.3)

Updates `helm.sh/helm/v3` from 3.15.2 to 3.15.3
- [Release notes](https://github.com/helm/helm/releases)
- [Commits](https://github.com/helm/helm/compare/v3.15.2...v3.15.3)

Updates `k8s.io/kubelet` from 0.30.2 to 0.30.3
- [Commits](https://github.com/kubernetes/kubelet/compare/v0.30.2...v0.30.3)

Updates `k8s.io/metrics` from 0.30.2 to 0.30.3
- [Commits](https://github.com/kubernetes/metrics/compare/v0.30.2...v0.30.3)

---
updated-dependencies:
- dependency-name: k8s.io/api
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/apiextensions-apiserver
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/apimachinery
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/apiserver
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/cli-runtime
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/client-go
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: helm.sh/helm/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/kubelet
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/metrics
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-23 00:20:09 +00:00
Gerard Nguyen 04e656a0a5 fix: [sc-106256] Add missing uri field to troubleshoot.sh types (#1578)
* new no-uri flag for preflight
* implement load additional spec from URIs
2024-07-19 08:23:55 +10:00
dependabot[bot]andlnx01 790c8d4bde chore(deps): bump helm.sh/helm/v3 from 3.15.2 to 3.15.3 in /examples/sdk/helm-template in the security group (#1577)
chore(deps): bump helm.sh/helm/v3

Bumps the security group in /examples/sdk/helm-template with 1 update: [helm.sh/helm/v3](https://github.com/helm/helm).


Updates `helm.sh/helm/v3` from 3.15.2 to 3.15.3
- [Release notes](https://github.com/helm/helm/releases)
- [Commits](https://github.com/helm/helm/compare/v3.15.2...v3.15.3)

---
updated-dependencies:
- dependency-name: helm.sh/helm/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-16 00:20:26 +00:00
Gerard Nguyen 4e999d6bfb fix: [sc-106256] Add missing uri field to troubleshoot.sh types (#1574)
add uri field for top level type
2024-07-15 13:07:04 +10:00
dependabot[bot]andlnx01 403b1ceccf chore(deps): bump the security group with 4 updates (#1573)
Bumps the security group with 4 updates: [go.opentelemetry.io/otel](https://github.com/open-telemetry/opentelemetry-go), [go.opentelemetry.io/otel/sdk](https://github.com/open-telemetry/opentelemetry-go), [golang.org/x/mod](https://github.com/golang/mod) and [golang.org/x/net](https://github.com/golang/net).


Updates `go.opentelemetry.io/otel` from 1.27.0 to 1.28.0
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.27.0...v1.28.0)

Updates `go.opentelemetry.io/otel/sdk` from 1.27.0 to 1.28.0
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.27.0...v1.28.0)

Updates `golang.org/x/mod` from 0.18.0 to 0.19.0
- [Commits](https://github.com/golang/mod/compare/v0.18.0...v0.19.0)

Updates `golang.org/x/net` from 0.26.0 to 0.27.0
- [Commits](https://github.com/golang/net/compare/v0.26.0...v0.27.0)

---
updated-dependencies:
- dependency-name: go.opentelemetry.io/otel
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: go.opentelemetry.io/otel/sdk
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: golang.org/x/mod
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-09 00:19:26 +00:00
Gerard Nguyen 8173759e52 feat: [sc-106927] Allow kernelConfig analyser to check kernel capability is either built in or loaded for EC host preflights (#1572)
* allow multiple value in kernel config check

* update unit test
2024-07-09 09:45:42 +10:00
Gerard Nguyen f5f02f5a80 fix: [sc-107456] exec collector is running in all pods matched the selector (#1571)
only exec in 1 pod
2024-07-08 09:31:29 +10:00
Gerard Nguyen e882f44ae9 Gerard/sc 106216/b registry image collector (#1570)
* update registry auth with username and password

* add unit test
2024-07-03 08:06:37 +10:00
dependabot[bot]andlnx01 d79ff950ca chore(deps): bump the security group with 3 updates (#1569)
Bumps the security group with 3 updates: [github.com/containers/image/v5](https://github.com/containers/image), [github.com/hashicorp/go-getter](https://github.com/hashicorp/go-getter) and [k8s.io/klog/v2](https://github.com/kubernetes/klog).


Updates `github.com/containers/image/v5` from 5.31.0 to 5.31.1
- [Release notes](https://github.com/containers/image/releases)
- [Commits](https://github.com/containers/image/compare/v5.31.0...v5.31.1)

Updates `github.com/hashicorp/go-getter` from 1.7.4 to 1.7.5
- [Release notes](https://github.com/hashicorp/go-getter/releases)
- [Changelog](https://github.com/hashicorp/go-getter/blob/main/.goreleaser.yml)
- [Commits](https://github.com/hashicorp/go-getter/compare/v1.7.4...v1.7.5)

Updates `k8s.io/klog/v2` from 2.130.0 to 2.130.1
- [Release notes](https://github.com/kubernetes/klog/releases)
- [Changelog](https://github.com/kubernetes/klog/blob/main/RELEASE.md)
- [Commits](https://github.com/kubernetes/klog/compare/v2.130.0...v2.130.1)

---
updated-dependencies:
- dependency-name: github.com/containers/image/v5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: github.com/hashicorp/go-getter
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/klog/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-25 00:19:09 +00:00
Gerard Nguyen 191ebdb598 feat: [sc-106759] Troubleshoot: uri field only download when we're not downloading (#1567)
* remove uri: when url is provided
2024-06-24 10:12:41 +10:00
Gerard Nguyen edfa01c5c4 feat: [sc-106625] http analyzer for in-cluster (#1566)
* http analzyer for in-cluster
* make check-schemas
2024-06-19 12:14:37 +10:00
dependabot[bot]andlnx01 18ec6adc12 chore(deps): bump helm.sh/helm/v3 from 3.15.1 to 3.15.2 in /examples/sdk/helm-template in the security group (#1564)
chore(deps): bump helm.sh/helm/v3

Bumps the security group in /examples/sdk/helm-template with 1 update: [helm.sh/helm/v3](https://github.com/helm/helm).


Updates `helm.sh/helm/v3` from 3.15.1 to 3.15.2
- [Release notes](https://github.com/helm/helm/releases)
- [Commits](https://github.com/helm/helm/compare/v3.15.1...v3.15.2)

---
updated-dependencies:
- dependency-name: helm.sh/helm/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-18 06:06:30 +00:00
dependabot[bot]andlnx01 15b908f9e0 chore(deps): bump the security group with 12 updates (#1565)
Bumps the security group with 12 updates:

| Package | From | To |
| --- | --- | --- |
| [github.com/spf13/cobra](https://github.com/spf13/cobra) | `1.8.0` | `1.8.1` |
| [github.com/vmware-tanzu/velero](https://github.com/vmware-tanzu/velero) | `1.13.2` | `1.14.0` |
| [k8s.io/api](https://github.com/kubernetes/api) | `0.30.1` | `0.30.2` |
| [k8s.io/apiextensions-apiserver](https://github.com/kubernetes/apiextensions-apiserver) | `0.30.1` | `0.30.2` |
| [k8s.io/apimachinery](https://github.com/kubernetes/apimachinery) | `0.30.1` | `0.30.2` |
| [k8s.io/apiserver](https://github.com/kubernetes/apiserver) | `0.30.1` | `0.30.2` |
| [k8s.io/cli-runtime](https://github.com/kubernetes/cli-runtime) | `0.30.1` | `0.30.2` |
| [k8s.io/client-go](https://github.com/kubernetes/client-go) | `0.30.1` | `0.30.2` |
| [k8s.io/klog/v2](https://github.com/kubernetes/klog) | `2.120.1` | `2.130.0` |
| [helm.sh/helm/v3](https://github.com/helm/helm) | `3.15.1` | `3.15.2` |
| [k8s.io/kubelet](https://github.com/kubernetes/kubelet) | `0.30.1` | `0.30.2` |
| [k8s.io/metrics](https://github.com/kubernetes/metrics) | `0.30.1` | `0.30.2` |


Updates `github.com/spf13/cobra` from 1.8.0 to 1.8.1
- [Release notes](https://github.com/spf13/cobra/releases)
- [Commits](https://github.com/spf13/cobra/compare/v1.8.0...v1.8.1)

Updates `github.com/vmware-tanzu/velero` from 1.13.2 to 1.14.0
- [Release notes](https://github.com/vmware-tanzu/velero/releases)
- [Changelog](https://github.com/vmware-tanzu/velero/blob/main/CHANGELOG.md)
- [Commits](https://github.com/vmware-tanzu/velero/compare/v1.13.2...v1.14.0)

Updates `k8s.io/api` from 0.30.1 to 0.30.2
- [Commits](https://github.com/kubernetes/api/compare/v0.30.1...v0.30.2)

Updates `k8s.io/apiextensions-apiserver` from 0.30.1 to 0.30.2
- [Release notes](https://github.com/kubernetes/apiextensions-apiserver/releases)
- [Commits](https://github.com/kubernetes/apiextensions-apiserver/compare/v0.30.1...v0.30.2)

Updates `k8s.io/apimachinery` from 0.30.1 to 0.30.2
- [Commits](https://github.com/kubernetes/apimachinery/compare/v0.30.1...v0.30.2)

Updates `k8s.io/apiserver` from 0.30.1 to 0.30.2
- [Commits](https://github.com/kubernetes/apiserver/compare/v0.30.1...v0.30.2)

Updates `k8s.io/cli-runtime` from 0.30.1 to 0.30.2
- [Commits](https://github.com/kubernetes/cli-runtime/compare/v0.30.1...v0.30.2)

Updates `k8s.io/client-go` from 0.30.1 to 0.30.2
- [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kubernetes/client-go/compare/v0.30.1...v0.30.2)

Updates `k8s.io/klog/v2` from 2.120.1 to 2.130.0
- [Release notes](https://github.com/kubernetes/klog/releases)
- [Changelog](https://github.com/kubernetes/klog/blob/main/RELEASE.md)
- [Commits](https://github.com/kubernetes/klog/compare/v2.120.1...v2.130.0)

Updates `helm.sh/helm/v3` from 3.15.1 to 3.15.2
- [Release notes](https://github.com/helm/helm/releases)
- [Commits](https://github.com/helm/helm/compare/v3.15.1...v3.15.2)

Updates `k8s.io/kubelet` from 0.30.1 to 0.30.2
- [Commits](https://github.com/kubernetes/kubelet/compare/v0.30.1...v0.30.2)

Updates `k8s.io/metrics` from 0.30.1 to 0.30.2
- [Commits](https://github.com/kubernetes/metrics/compare/v0.30.1...v0.30.2)

---
updated-dependencies:
- dependency-name: github.com/spf13/cobra
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: github.com/vmware-tanzu/velero
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: k8s.io/api
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/apiextensions-apiserver
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/apimachinery
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/apiserver
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/cli-runtime
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/client-go
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/klog/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: helm.sh/helm/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/kubelet
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/metrics
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-18 00:20:00 +00:00
dependabot[bot]andlnx01 a9c5baca14 chore(deps): bump goreleaser/goreleaser-action from 5 to 6 (#1562)
Bumps [goreleaser/goreleaser-action](https://github.com/goreleaser/goreleaser-action) from 5 to 6.
- [Release notes](https://github.com/goreleaser/goreleaser-action/releases)
- [Commits](https://github.com/goreleaser/goreleaser-action/compare/v5...v6)

---
updated-dependencies:
- dependency-name: goreleaser/goreleaser-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-13 17:28:22 +12:00
dependabot[bot]andlnx01 5778d4656a chore(deps): bump the security group across 1 directory with 8 updates (#1561)
Bumps the security group with 7 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [github.com/microsoft/go-mssqldb](https://github.com/microsoft/go-mssqldb) | `1.7.1` | `1.7.2` |
| [github.com/shirou/gopsutil/v3](https://github.com/shirou/gopsutil) | `3.24.4` | `3.24.5` |
| [github.com/spf13/viper](https://github.com/spf13/viper) | `1.18.2` | `1.19.0` |
| [golang.org/x/mod](https://github.com/golang/mod) | `0.17.0` | `0.18.0` |
| [sigs.k8s.io/controller-runtime](https://github.com/kubernetes-sigs/controller-runtime) | `0.18.3` | `0.18.4` |
| [sigs.k8s.io/e2e-framework](https://github.com/kubernetes-sigs/e2e-framework) | `0.3.0` | `0.4.0` |
| [golang.org/x/net](https://github.com/golang/net) | `0.25.0` | `0.26.0` |



Updates `github.com/microsoft/go-mssqldb` from 1.7.1 to 1.7.2
- [Release notes](https://github.com/microsoft/go-mssqldb/releases)
- [Changelog](https://github.com/microsoft/go-mssqldb/blob/main/CHANGELOG.md)
- [Commits](https://github.com/microsoft/go-mssqldb/compare/v1.7.1...v1.7.2)

Updates `github.com/shirou/gopsutil/v3` from 3.24.4 to 3.24.5
- [Release notes](https://github.com/shirou/gopsutil/releases)
- [Commits](https://github.com/shirou/gopsutil/compare/v3.24.4...v3.24.5)

Updates `github.com/spf13/viper` from 1.18.2 to 1.19.0
- [Release notes](https://github.com/spf13/viper/releases)
- [Commits](https://github.com/spf13/viper/compare/v1.18.2...v1.19.0)

Updates `golang.org/x/mod` from 0.17.0 to 0.18.0
- [Commits](https://github.com/golang/mod/compare/v0.17.0...v0.18.0)

Updates `sigs.k8s.io/controller-runtime` from 0.18.3 to 0.18.4
- [Release notes](https://github.com/kubernetes-sigs/controller-runtime/releases)
- [Changelog](https://github.com/kubernetes-sigs/controller-runtime/blob/main/RELEASE.md)
- [Commits](https://github.com/kubernetes-sigs/controller-runtime/compare/v0.18.3...v0.18.4)

Updates `sigs.k8s.io/e2e-framework` from 0.3.0 to 0.4.0
- [Release notes](https://github.com/kubernetes-sigs/e2e-framework/releases)
- [Changelog](https://github.com/kubernetes-sigs/e2e-framework/blob/main/RELEASE.md)
- [Commits](https://github.com/kubernetes-sigs/e2e-framework/compare/v0.3.0...v0.4.0)

Updates `golang.org/x/net` from 0.25.0 to 0.26.0
- [Commits](https://github.com/golang/net/compare/v0.25.0...v0.26.0)

Updates `golang.org/x/text` from 0.15.0 to 0.16.0
- [Release notes](https://github.com/golang/text/releases)
- [Commits](https://github.com/golang/text/compare/v0.15.0...v0.16.0)

---
updated-dependencies:
- dependency-name: github.com/microsoft/go-mssqldb
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: github.com/shirou/gopsutil/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: github.com/spf13/viper
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: golang.org/x/mod
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: sigs.k8s.io/controller-runtime
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: sigs.k8s.io/e2e-framework
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: golang.org/x/text
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-10 00:20:06 +00:00
Xav Paice 905c9771bc update Go to 1.22.3 (#1560) 2024-06-10 10:43:12 +12:00
Evans Mungai ce155270c8 fix: Use correct cron job kind when discovering API versions (#1554)
* fix: Use correct cron job kind when discovering API versions

* Fix failing e2e test
2024-05-31 07:23:56 +01:00
dependabot[bot]andlnx01 91da8f13bb chore(deps): bump azure/docker-login from 1 to 2 (#1552)
Bumps [azure/docker-login](https://github.com/azure/docker-login) from 1 to 2.
- [Release notes](https://github.com/azure/docker-login/releases)
- [Commits](https://github.com/azure/docker-login/compare/v1...v2)

---
updated-dependencies:
- dependency-name: azure/docker-login
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-28 09:49:06 +01:00
dependabot[bot]andlnx01 1a8aff1d79 chore(deps): bump the security group with 9 updates (#1551)
Bumps the security group with 9 updates:

| Package | From | To |
| --- | --- | --- |
| [github.com/containers/image/v5](https://github.com/containers/image) | `5.30.1` | `5.31.0` |
| [github.com/go-logr/logr](https://github.com/go-logr/logr) | `1.4.1` | `1.4.2` |
| [github.com/jackc/pgx/v5](https://github.com/jackc/pgx) | `5.5.5` | `5.6.0` |
| [go.opentelemetry.io/otel](https://github.com/open-telemetry/opentelemetry-go) | `1.26.0` | `1.27.0` |
| [go.opentelemetry.io/otel/sdk](https://github.com/open-telemetry/opentelemetry-go) | `1.26.0` | `1.27.0` |
| [golang.org/x/exp](https://github.com/golang/exp) | `0.0.0-20240222234643-814bf88cf225` | `0.0.0-20240506185415-9bf2ced13842` |
| [sigs.k8s.io/controller-runtime](https://github.com/kubernetes-sigs/controller-runtime) | `0.18.2` | `0.18.3` |
| [github.com/hashicorp/go-version](https://github.com/hashicorp/go-version) | `1.6.0` | `1.7.0` |
| [helm.sh/helm/v3](https://github.com/helm/helm) | `3.15.0` | `3.15.1` |


Updates `github.com/containers/image/v5` from 5.30.1 to 5.31.0
- [Release notes](https://github.com/containers/image/releases)
- [Commits](https://github.com/containers/image/compare/v5.30.1...v5.31.0)

Updates `github.com/go-logr/logr` from 1.4.1 to 1.4.2
- [Release notes](https://github.com/go-logr/logr/releases)
- [Changelog](https://github.com/go-logr/logr/blob/master/CHANGELOG.md)
- [Commits](https://github.com/go-logr/logr/compare/v1.4.1...v1.4.2)

Updates `github.com/jackc/pgx/v5` from 5.5.5 to 5.6.0
- [Changelog](https://github.com/jackc/pgx/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jackc/pgx/compare/v5.5.5...v5.6.0)

Updates `go.opentelemetry.io/otel` from 1.26.0 to 1.27.0
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.26.0...v1.27.0)

Updates `go.opentelemetry.io/otel/sdk` from 1.26.0 to 1.27.0
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.26.0...v1.27.0)

Updates `golang.org/x/exp` from 0.0.0-20240222234643-814bf88cf225 to 0.0.0-20240506185415-9bf2ced13842
- [Commits](https://github.com/golang/exp/commits)

Updates `sigs.k8s.io/controller-runtime` from 0.18.2 to 0.18.3
- [Release notes](https://github.com/kubernetes-sigs/controller-runtime/releases)
- [Changelog](https://github.com/kubernetes-sigs/controller-runtime/blob/main/RELEASE.md)
- [Commits](https://github.com/kubernetes-sigs/controller-runtime/compare/v0.18.2...v0.18.3)

Updates `github.com/hashicorp/go-version` from 1.6.0 to 1.7.0
- [Release notes](https://github.com/hashicorp/go-version/releases)
- [Changelog](https://github.com/hashicorp/go-version/blob/main/CHANGELOG.md)
- [Commits](https://github.com/hashicorp/go-version/compare/v1.6.0...v1.7.0)

Updates `helm.sh/helm/v3` from 3.15.0 to 3.15.1
- [Release notes](https://github.com/helm/helm/releases)
- [Commits](https://github.com/helm/helm/compare/v3.15.0...v3.15.1)

---
updated-dependencies:
- dependency-name: github.com/containers/image/v5
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: github.com/go-logr/logr
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: github.com/jackc/pgx/v5
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: go.opentelemetry.io/otel
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: go.opentelemetry.io/otel/sdk
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: golang.org/x/exp
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: sigs.k8s.io/controller-runtime
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: github.com/hashicorp/go-version
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: helm.sh/helm/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-27 17:19:28 -07:00
dependabot[bot]andlnx01 ece20d3c2c chore(deps): bump helm.sh/helm/v3 from 3.15.0 to 3.15.1 in /examples/sdk/helm-template in the security group (#1550)
chore(deps): bump helm.sh/helm/v3

Bumps the security group in /examples/sdk/helm-template with 1 update: [helm.sh/helm/v3](https://github.com/helm/helm).


Updates `helm.sh/helm/v3` from 3.15.0 to 3.15.1
- [Release notes](https://github.com/helm/helm/releases)
- [Commits](https://github.com/helm/helm/compare/v3.15.0...v3.15.1)

---
updated-dependencies:
- dependency-name: helm.sh/helm/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-27 17:18:57 -07:00
Gerard Nguyen 80e5fac07c feat: New host collector and analyzer for Kernel Configs (#1546)
* new struct and update schemas

* implement Collect function

* add kernel config to collector struct

* generate kernel config analyzer schema

* implement kernel config analyzer

* fail on no match in pass outcome

* run make check-schemas

* fix failed unit test

* update from code review

* add selectedConfigs field

* run make check-schemas
2024-05-27 09:55:39 +10:00
Dexter Yan 51c07b42c3 feat(analyzer): let cluster resource case insensitive to fix name inconsistent (#1547)
* feat(analyzer): let cluster resource case insensitive
2024-05-22 11:37:39 +12:00
bd7bae6302 chore(deps): bump the security group with 9 updates (#1549)
* ---
updated-dependencies:
- dependency-name: k8s.io/api
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/apiextensions-apiserver
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/apimachinery
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/apiserver
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/cli-runtime
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/client-go
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: helm.sh/helm/v3
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: k8s.io/kubelet
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/metrics
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
...

Signed-off-by: dependabot[bot] <support@github.com>

* Regenerate CR schemas

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Evans Mungai <evans@replicated.com>
2024-05-21 12:07:50 +00:00
dependabot[bot]andlnx01 9d41460d33 chore(deps): bump helm.sh/helm/v3 from 3.14.4 to 3.15.0 in /examples/sdk/helm-template in the security group (#1548)
---
updated-dependencies:
- dependency-name: helm.sh/helm/v3
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-21 00:19:08 +00:00
Gerard Nguyen fb0f81d076 bug: [sc-103753] Host analysers are not deduplicating during multiple spec merges #1485 (#1542)
* dedupe host collector and analyzer

* dedup analyzer

* add unit test

* use generic
2024-05-17 09:34:29 +10:00
Evans Mungai 78bbea18ac feat: Prefer embedded-cluster over k0s when detecting distro (#1544)
* feat: Prefer embedded-cluster over k0s when detecting distro

* Implement check for embedded cluster detection
2024-05-15 09:26:03 +01:00
dependabot[bot]andlnx01 224d55b076 chore(deps): bump the security group with 2 updates (#1545)
Bumps the security group with 2 updates: [github.com/containers/image/v5](https://github.com/containers/image) and [github.com/fatih/color](https://github.com/fatih/color).


Updates `github.com/containers/image/v5` from 5.30.0 to 5.30.1
- [Release notes](https://github.com/containers/image/releases)
- [Commits](https://github.com/containers/image/compare/v5.30.0...v5.30.1)

Updates `github.com/fatih/color` from 1.16.0 to 1.17.0
- [Release notes](https://github.com/fatih/color/releases)
- [Commits](https://github.com/fatih/color/compare/v1.16.0...v1.17.0)

---
updated-dependencies:
- dependency-name: github.com/containers/image/v5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: github.com/fatih/color
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-14 00:18:29 +00:00
dependabot[bot]andlnx01 db967d2896 chore(deps): bump the security group with 4 updates (#1543)
Bumps the security group with 4 updates: [github.com/shirou/gopsutil/v3](https://github.com/shirou/gopsutil), [sigs.k8s.io/controller-runtime](https://github.com/kubernetes-sigs/controller-runtime), [golang.org/x/net](https://github.com/golang/net) and [golang.org/x/text](https://github.com/golang/text).


Updates `github.com/shirou/gopsutil/v3` from 3.24.3 to 3.24.4
- [Release notes](https://github.com/shirou/gopsutil/releases)
- [Commits](https://github.com/shirou/gopsutil/compare/v3.24.3...v3.24.4)

Updates `sigs.k8s.io/controller-runtime` from 0.18.0 to 0.18.2
- [Release notes](https://github.com/kubernetes-sigs/controller-runtime/releases)
- [Changelog](https://github.com/kubernetes-sigs/controller-runtime/blob/main/RELEASE.md)
- [Commits](https://github.com/kubernetes-sigs/controller-runtime/compare/v0.18.0...v0.18.2)

Updates `golang.org/x/net` from 0.24.0 to 0.25.0
- [Commits](https://github.com/golang/net/compare/v0.24.0...v0.25.0)

Updates `golang.org/x/text` from 0.14.0 to 0.15.0
- [Release notes](https://github.com/golang/text/releases)
- [Commits](https://github.com/golang/text/compare/v0.14.0...v0.15.0)

---
updated-dependencies:
- dependency-name: github.com/shirou/gopsutil/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: sigs.k8s.io/controller-runtime
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: golang.org/x/text
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-07 00:18:35 +00:00
Gerard Nguyen 088f0321e7 feat: [sc-103119] URI is not replacing the spec but merging instead (#1541)
* only replace spec that has uri

* add unit test

* fix unit tests from code review
2024-05-03 11:36:27 +01:00
Evans Mungai aeaac7a70f Revert "feat: URI is not replacing the spec but merging instead (#1537) (#1539)
Revert "feat: [sc-103119] URI is not replacing the spec but merging instead (#1537)"

This reverts commit c2f72ecd0c.
2024-05-01 14:38:46 +01:00
Gerard Nguyen 6b368f2221 feat: [sc-103754] Be able to detect search domain misconfiguration #1391 (#1534)
* new collector dns

* implement DNS collector

* add dns service and endpoints check

* add nil check on retrieve endpoints
2024-05-01 07:04:20 +10:00
Dexter YanandGerard Nguyen cb5db1733a feat(analyzer): make sure ReplicaSetStatus has valid result (#1538)
* feat(analyzer): make sure ReplicaSetStatus has valid result
---------

Co-authored-by: Gerard Nguyen <gerard@replicated.com>
2024-05-01 09:02:45 +12:00
Gerard Nguyen c2f72ecd0c feat: [sc-103119] URI is not replacing the spec but merging instead (#1537)
fix uri spec to replace origin spec
2024-04-30 14:13:35 +12:00
Dexter Yan f3bad5f409 fix(collector): fix helm collector with a nil error return to error list (#1535) 2024-04-29 12:19:34 +12:00
dependabot[bot]andlnx01 f438467003 chore(deps): bump the security group across 1 directory with 5 updates (#1531)
Bumps the security group with 5 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [github.com/microsoft/go-mssqldb](https://github.com/microsoft/go-mssqldb) | `1.7.0` | `1.7.1` |
| [github.com/vmware-tanzu/velero](https://github.com/vmware-tanzu/velero) | `1.13.1` | `1.13.2` |
| [go.opentelemetry.io/otel](https://github.com/open-telemetry/opentelemetry-go) | `1.25.0` | `1.26.0` |
| [go.opentelemetry.io/otel/sdk](https://github.com/open-telemetry/opentelemetry-go) | `1.25.0` | `1.26.0` |
| [sigs.k8s.io/controller-runtime](https://github.com/kubernetes-sigs/controller-runtime) | `0.17.3` | `0.18.0` |



Updates `github.com/microsoft/go-mssqldb` from 1.7.0 to 1.7.1
- [Release notes](https://github.com/microsoft/go-mssqldb/releases)
- [Changelog](https://github.com/microsoft/go-mssqldb/blob/main/CHANGELOG.md)
- [Commits](https://github.com/microsoft/go-mssqldb/compare/v1.7.0...v1.7.1)

Updates `github.com/vmware-tanzu/velero` from 1.13.1 to 1.13.2
- [Release notes](https://github.com/vmware-tanzu/velero/releases)
- [Changelog](https://github.com/vmware-tanzu/velero/blob/main/CHANGELOG.md)
- [Commits](https://github.com/vmware-tanzu/velero/compare/v1.13.1...v1.13.2)

Updates `go.opentelemetry.io/otel` from 1.25.0 to 1.26.0
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.25.0...v1.26.0)

Updates `go.opentelemetry.io/otel/sdk` from 1.25.0 to 1.26.0
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.25.0...v1.26.0)

Updates `sigs.k8s.io/controller-runtime` from 0.17.3 to 0.18.0
- [Release notes](https://github.com/kubernetes-sigs/controller-runtime/releases)
- [Changelog](https://github.com/kubernetes-sigs/controller-runtime/blob/main/RELEASE.md)
- [Commits](https://github.com/kubernetes-sigs/controller-runtime/compare/v0.17.3...v0.18.0)

---
updated-dependencies:
- dependency-name: github.com/microsoft/go-mssqldb
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: github.com/vmware-tanzu/velero
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: go.opentelemetry.io/otel
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: go.opentelemetry.io/otel/sdk
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: sigs.k8s.io/controller-runtime
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-26 15:35:07 +12:00
Evans Mungai a374b0a3ab feat: Detect EC as a distribution (#1529) 2024-04-25 17:18:52 +01:00
Evans Mungai 6aaba59ebd feat: Detect k0s distribution in analyser (#1527) 2024-04-25 15:29:37 +01:00
Andrew Lavery f18b5d754e update k8s imports to v0.30.0 and address changed function signature (#1528)
* update k8s imports to v0.30.0 and address changed function signature

* update schemas
2024-04-24 23:05:37 +09:00
dependabot[bot]andlnx01 2ede46ed58 chore(deps): bump the security group with 2 updates (#1524)
Bumps the security group with 2 updates: [github.com/hashicorp/go-getter](https://github.com/hashicorp/go-getter) and [helm.sh/helm/v3](https://github.com/helm/helm).


Updates `github.com/hashicorp/go-getter` from 1.7.3 to 1.7.4
- [Release notes](https://github.com/hashicorp/go-getter/releases)
- [Changelog](https://github.com/hashicorp/go-getter/blob/main/.goreleaser.yml)
- [Commits](https://github.com/hashicorp/go-getter/compare/v1.7.3...v1.7.4)

Updates `helm.sh/helm/v3` from 3.14.3 to 3.14.4
- [Release notes](https://github.com/helm/helm/releases)
- [Commits](https://github.com/helm/helm/compare/v3.14.3...v3.14.4)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/go-getter
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: helm.sh/helm/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-16 14:58:32 +12:00
dependabot[bot]andlnx01 07d1747d81 chore(deps): bump helm.sh/helm/v3 from 3.14.3 to 3.14.4 in /examples/sdk/helm-template in the security group (#1525)
chore(deps): bump helm.sh/helm/v3

Bumps the security group in /examples/sdk/helm-template with 1 update: [helm.sh/helm/v3](https://github.com/helm/helm).


Updates `helm.sh/helm/v3` from 3.14.3 to 3.14.4
- [Release notes](https://github.com/helm/helm/releases)
- [Commits](https://github.com/helm/helm/compare/v3.14.3...v3.14.4)

---
updated-dependencies:
- dependency-name: helm.sh/helm/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-16 00:18:04 +00:00
Evans MungaiandDexter Yan db871e6889 feat: node metrics analyser (#1520)
* feat: node metrics analyser

The analyser only checks PVC usage at the moment. More analysers
can be added on a need to have basis

* Add tests

* Fix flaky test by waiting for goldpinger pods to start

* Fix how outcomes get checked

* Fix catch all outcome condition

* Fix test

* feat: node metrics analyser

The analyser only checks PVC usage at the moment. More analysers
can be added on a need to have basis

* Add tests

* Fix flaky test by waiting for goldpinger pods to start

* Fix how outcomes get checked

* Fix catch all outcome condition

* Fix test

* Regenerate schemas

* Fix failing test

---------

Co-authored-by: Dexter Yan <yanshaocong@gmail.com>
2024-04-09 12:14:10 +01:00
dependabot[bot]andlnx01 dc4403811b chore(deps): bump the security group with 6 updates (#1522)
Bumps the security group with 6 updates:

| Package | From | To |
| --- | --- | --- |
| [go.opentelemetry.io/otel](https://github.com/open-telemetry/opentelemetry-go) | `1.24.0` | `1.25.0` |
| [go.opentelemetry.io/otel/sdk](https://github.com/open-telemetry/opentelemetry-go) | `1.24.0` | `1.25.0` |
| [golang.org/x/mod](https://github.com/golang/mod) | `0.16.0` | `0.17.0` |
| [golang.org/x/sync](https://github.com/golang/sync) | `0.6.0` | `0.7.0` |
| [sigs.k8s.io/controller-runtime](https://github.com/kubernetes-sigs/controller-runtime) | `0.17.2` | `0.17.3` |
| [golang.org/x/net](https://github.com/golang/net) | `0.22.0` | `0.24.0` |


Updates `go.opentelemetry.io/otel` from 1.24.0 to 1.25.0
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.24.0...v1.25.0)

Updates `go.opentelemetry.io/otel/sdk` from 1.24.0 to 1.25.0
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.24.0...v1.25.0)

Updates `golang.org/x/mod` from 0.16.0 to 0.17.0
- [Commits](https://github.com/golang/mod/compare/v0.16.0...v0.17.0)

Updates `golang.org/x/sync` from 0.6.0 to 0.7.0
- [Commits](https://github.com/golang/sync/compare/v0.6.0...v0.7.0)

Updates `sigs.k8s.io/controller-runtime` from 0.17.2 to 0.17.3
- [Release notes](https://github.com/kubernetes-sigs/controller-runtime/releases)
- [Changelog](https://github.com/kubernetes-sigs/controller-runtime/blob/main/RELEASE.md)
- [Commits](https://github.com/kubernetes-sigs/controller-runtime/compare/v0.17.2...v0.17.3)

Updates `golang.org/x/net` from 0.22.0 to 0.24.0
- [Commits](https://github.com/golang/net/compare/v0.22.0...v0.24.0)

---
updated-dependencies:
- dependency-name: go.opentelemetry.io/otel
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: go.opentelemetry.io/otel/sdk
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: golang.org/x/mod
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: golang.org/x/sync
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: sigs.k8s.io/controller-runtime
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-09 00:18:07 +00:00
Ethan Mosbaugh 6f7acec7b3 feat: distribution analyzer support for kind (#1521) 2024-04-07 09:24:42 +12:00
Evans Mungai 123d17ab4a feat: node metrics collector (#1516)
* feat: node metrics collector

A collector to collect node metrics served by the API server as
per the documented API https://kubernetes.io/docs/reference/instrumentation/node-metrics/

* Update CRD schemas

* Add tests

* Remove clean from build target

* Update comments

* Commit missing tests

* Remove unnecessary log in tests
2024-04-02 14:59:55 +01:00
dependabot[bot]andlnx01 867c70619c chore(deps): bump the security group with 2 updates (#1519)
Bumps the security group with 2 updates: [github.com/go-sql-driver/mysql](https://github.com/go-sql-driver/mysql) and [github.com/shirou/gopsutil/v3](https://github.com/shirou/gopsutil).


Updates `github.com/go-sql-driver/mysql` from 1.8.0 to 1.8.1
- [Release notes](https://github.com/go-sql-driver/mysql/releases)
- [Changelog](https://github.com/go-sql-driver/mysql/blob/v1.8.1/CHANGELOG.md)
- [Commits](https://github.com/go-sql-driver/mysql/compare/v1.8.0...v1.8.1)

Updates `github.com/shirou/gopsutil/v3` from 3.24.2 to 3.24.3
- [Release notes](https://github.com/shirou/gopsutil/releases)
- [Commits](https://github.com/shirou/gopsutil/compare/v3.24.2...v3.24.3)

---
updated-dependencies:
- dependency-name: github.com/go-sql-driver/mysql
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: github.com/shirou/gopsutil/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-02 00:18:00 +00:00
Evans Mungai c9830de736 chore: Update CLI prompt to run command as root (#1517) 2024-03-28 19:13:33 +00:00
Evans Mungai ca5ff88964 chore: Update code generator and controller tools (#1515) 2024-03-28 11:52:15 +00:00
Evans Mungai e6aff48f1b feat: Prompt for privileged user if host collectors present in spec (#1513)
* feat: Prompt for privileged user if host collectors present

* Prompt preflight checks that have host collectors

* Show cursor before prompting
2024-03-28 11:51:19 +00:00
Gerard Nguyen 76c52d2b93 New JSON field in HTTP request collector if any (#1511)
* add new raw_json field to http collector

* add unit test
2024-03-28 17:08:51 +11:00
dependabot[bot]andlnx01 bece801ba8 chore(deps): bump github.com/distribution/distribution/v3 from 3.0.0-20221208165359-362910506bc2 to 3.0.0-alpha.1 (#1466)
chore(deps): bump github.com/distribution/distribution/v3

Bumps [github.com/distribution/distribution/v3](https://github.com/distribution/distribution) from 3.0.0-20221208165359-362910506bc2 to 3.0.0-alpha.1.
- [Release notes](https://github.com/distribution/distribution/releases)
- [Commits](https://github.com/distribution/distribution/commits/v3.0.0-alpha.1)

---
updated-dependencies:
- dependency-name: github.com/distribution/distribution/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-25 20:00:07 +13:00
dependabot[bot]andlnx01 72701fa4d2 chore(deps): bump github.com/docker/docker from 25.0.3+incompatible to 25.0.5+incompatible (#1510)
chore(deps): bump github.com/docker/docker

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 25.0.3+incompatible to 25.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](https://github.com/docker/docker/compare/v25.0.3...v25.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-21 00:18:26 +00:00
dependabot[bot]andlnx01 7eae0fe687 chore(deps): bump the security group with 8 updates (#1509)
Bumps the security group with 8 updates:

| Package | From | To |
| --- | --- | --- |
| [github.com/vmware-tanzu/velero](https://github.com/vmware-tanzu/velero) | `1.13.0` | `1.13.1` |
| [k8s.io/api](https://github.com/kubernetes/api) | `0.29.2` | `0.29.3` |
| [k8s.io/apiextensions-apiserver](https://github.com/kubernetes/apiextensions-apiserver) | `0.29.2` | `0.29.3` |
| [k8s.io/apimachinery](https://github.com/kubernetes/apimachinery) | `0.29.2` | `0.29.3` |
| [k8s.io/apiserver](https://github.com/kubernetes/apiserver) | `0.29.2` | `0.29.3` |
| [k8s.io/cli-runtime](https://github.com/kubernetes/cli-runtime) | `0.29.2` | `0.29.3` |
| [k8s.io/client-go](https://github.com/kubernetes/client-go) | `0.29.2` | `0.29.3` |
| [k8s.io/metrics](https://github.com/kubernetes/metrics) | `0.29.2` | `0.29.3` |


Updates `github.com/vmware-tanzu/velero` from 1.13.0 to 1.13.1
- [Release notes](https://github.com/vmware-tanzu/velero/releases)
- [Changelog](https://github.com/vmware-tanzu/velero/blob/main/CHANGELOG.md)
- [Commits](https://github.com/vmware-tanzu/velero/compare/v1.13.0...v1.13.1)

Updates `k8s.io/api` from 0.29.2 to 0.29.3
- [Commits](https://github.com/kubernetes/api/compare/v0.29.2...v0.29.3)

Updates `k8s.io/apiextensions-apiserver` from 0.29.2 to 0.29.3
- [Release notes](https://github.com/kubernetes/apiextensions-apiserver/releases)
- [Commits](https://github.com/kubernetes/apiextensions-apiserver/compare/v0.29.2...v0.29.3)

Updates `k8s.io/apimachinery` from 0.29.2 to 0.29.3
- [Commits](https://github.com/kubernetes/apimachinery/compare/v0.29.2...v0.29.3)

Updates `k8s.io/apiserver` from 0.29.2 to 0.29.3
- [Commits](https://github.com/kubernetes/apiserver/compare/v0.29.2...v0.29.3)

Updates `k8s.io/cli-runtime` from 0.29.2 to 0.29.3
- [Commits](https://github.com/kubernetes/cli-runtime/compare/v0.29.2...v0.29.3)

Updates `k8s.io/client-go` from 0.29.2 to 0.29.3
- [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kubernetes/client-go/compare/v0.29.2...v0.29.3)

Updates `k8s.io/metrics` from 0.29.2 to 0.29.3
- [Commits](https://github.com/kubernetes/metrics/compare/v0.29.2...v0.29.3)

---
updated-dependencies:
- dependency-name: github.com/vmware-tanzu/velero
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/api
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/apiextensions-apiserver
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/apimachinery
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/apiserver
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/cli-runtime
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/client-go
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/metrics
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-19 00:17:50 +00:00
Gerard Nguyen 6f839b389d Quick fix to prevent panic on nil collector result (#1508)
* quick fix to prevent panic on nil collector result
* do not save pod details on error
2024-03-18 16:42:52 +11:00
dependabot[bot]andlnx01 ebe98ff2f1 chore(deps): bump the go_modules group group with 2 updates (#1507)
Bumps the go_modules group group with 2 updates: google.golang.org/protobuf and [helm.sh/helm/v3](https://github.com/helm/helm).


Updates `google.golang.org/protobuf` from 1.31.0 to 1.33.0

Updates `helm.sh/helm/v3` from 3.14.2 to 3.14.3
- [Release notes](https://github.com/helm/helm/releases)
- [Commits](https://github.com/helm/helm/compare/v3.14.2...v3.14.3)

---
updated-dependencies:
- dependency-name: google.golang.org/protobuf
  dependency-type: indirect
  dependency-group: go_modules-security-group
- dependency-name: helm.sh/helm/v3
  dependency-type: direct:production
  dependency-group: go_modules-security-group
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-14 00:17:47 +00:00
dependabot[bot]andlnx01 59624e88fd chore(deps): bump the go_modules group group in /examples/sdk/helm-template with 2 updates (#1506)
chore(deps): bump the go_modules group group

Bumps the go_modules group group in /examples/sdk/helm-template with 2 updates: [helm.sh/helm/v3](https://github.com/helm/helm) and google.golang.org/protobuf.


Updates `helm.sh/helm/v3` from 3.14.2 to 3.14.3
- [Release notes](https://github.com/helm/helm/releases)
- [Commits](https://github.com/helm/helm/compare/v3.14.2...v3.14.3)

Updates `google.golang.org/protobuf` from 1.31.0 to 1.33.0

---
updated-dependencies:
- dependency-name: helm.sh/helm/v3
  dependency-type: direct:production
  dependency-group: go_modules-security-group
- dependency-name: google.golang.org/protobuf
  dependency-type: indirect
  dependency-group: go_modules-security-group
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-14 00:17:18 +00:00
Evans Mungai 15446996f9 fix: Parse v1beta1 troubleshoot specs when using loader API (#1501) 2024-03-13 11:39:29 +00:00
dependabot[bot]andlnx01 c4237b6c40 chore(deps): bump the security group with 4 updates (#1503)
Bumps the security group with 4 updates: [github.com/containers/image/v5](https://github.com/containers/image), [github.com/go-sql-driver/mysql](https://github.com/go-sql-driver/mysql), [github.com/jackc/pgx/v5](https://github.com/jackc/pgx) and [golang.org/x/exp](https://github.com/golang/exp).


Updates `github.com/containers/image/v5` from 5.29.2 to 5.30.0
- [Release notes](https://github.com/containers/image/releases)
- [Commits](https://github.com/containers/image/compare/v5.29.2...v5.30.0)

Updates `github.com/go-sql-driver/mysql` from 1.7.1 to 1.8.0
- [Release notes](https://github.com/go-sql-driver/mysql/releases)
- [Changelog](https://github.com/go-sql-driver/mysql/blob/master/CHANGELOG.md)
- [Commits](https://github.com/go-sql-driver/mysql/compare/v1.7.1...v1.8.0)

Updates `github.com/jackc/pgx/v5` from 5.5.4 to 5.5.5
- [Changelog](https://github.com/jackc/pgx/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jackc/pgx/compare/v5.5.4...v5.5.5)

Updates `golang.org/x/exp` from 0.0.0-20231006140011-7918f672742d to 0.0.0-20240222234643-814bf88cf225
- [Commits](https://github.com/golang/exp/commits)

---
updated-dependencies:
- dependency-name: github.com/containers/image/v5
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: github.com/go-sql-driver/mysql
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: github.com/jackc/pgx/v5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: golang.org/x/exp
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-12 00:17:13 +00:00
Evans Mungai d0685ea81a fix: flaky goldpinger e2e test (#1499)
Installing the chart at times takes too long. We'll increase the time
that we wait for the application to be healthy
2024-03-07 17:19:22 +00:00
Gerard Nguyen 742e92f1ee New Event Analyzer (#1474)
* add new Event analyzer
2024-03-07 08:31:45 +13:00
Gerard Nguyen 553d709043 fix panic in Velero analyzer when there's no Velero deployment found (#1497)
* fix panic in Velero analyzer when there's no Velero deployment found

* do not omit error in find files
2024-03-05 21:58:37 +11:00
dependabot[bot]andlnx01 29435b1c15 chore(deps): bump the security group with 5 updates (#1498)
Bumps the security group with 5 updates:

| Package | From | To |
| --- | --- | --- |
| [github.com/jackc/pgx/v5](https://github.com/jackc/pgx) | `5.5.3` | `5.5.4` |
| [github.com/shirou/gopsutil/v3](https://github.com/shirou/gopsutil) | `3.24.1` | `3.24.2` |
| [github.com/stretchr/testify](https://github.com/stretchr/testify) | `1.8.4` | `1.9.0` |
| [golang.org/x/mod](https://github.com/golang/mod) | `0.15.0` | `0.16.0` |
| [golang.org/x/net](https://github.com/golang/net) | `0.21.0` | `0.22.0` |


Updates `github.com/jackc/pgx/v5` from 5.5.3 to 5.5.4
- [Changelog](https://github.com/jackc/pgx/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jackc/pgx/compare/v5.5.3...v5.5.4)

Updates `github.com/shirou/gopsutil/v3` from 3.24.1 to 3.24.2
- [Release notes](https://github.com/shirou/gopsutil/releases)
- [Commits](https://github.com/shirou/gopsutil/compare/v3.24.1...v3.24.2)

Updates `github.com/stretchr/testify` from 1.8.4 to 1.9.0
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.8.4...v1.9.0)

Updates `golang.org/x/mod` from 0.15.0 to 0.16.0
- [Commits](https://github.com/golang/mod/compare/v0.15.0...v0.16.0)

Updates `golang.org/x/net` from 0.21.0 to 0.22.0
- [Commits](https://github.com/golang/net/compare/v0.21.0...v0.22.0)

---
updated-dependencies:
- dependency-name: github.com/jackc/pgx/v5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: github.com/shirou/gopsutil/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: github.com/stretchr/testify
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: golang.org/x/mod
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-05 00:17:14 +00:00
dependabot[bot]andlnx01 a9b889e033 chore(deps): bump the security group with 3 updates (#1495)
Bumps the security group with 3 updates: [github.com/microsoft/go-mssqldb](https://github.com/microsoft/go-mssqldb), [go.opentelemetry.io/otel](https://github.com/open-telemetry/opentelemetry-go) and [go.opentelemetry.io/otel/sdk](https://github.com/open-telemetry/opentelemetry-go).


Updates `github.com/microsoft/go-mssqldb` from 1.6.0 to 1.7.0
- [Release notes](https://github.com/microsoft/go-mssqldb/releases)
- [Changelog](https://github.com/microsoft/go-mssqldb/blob/main/CHANGELOG.md)
- [Commits](https://github.com/microsoft/go-mssqldb/compare/v1.6.0...v1.7.0)

Updates `go.opentelemetry.io/otel` from 1.23.1 to 1.24.0
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.23.1...v1.24.0)

Updates `go.opentelemetry.io/otel/sdk` from 1.23.1 to 1.24.0
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.23.1...v1.24.0)

---
updated-dependencies:
- dependency-name: github.com/microsoft/go-mssqldb
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: go.opentelemetry.io/otel
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: go.opentelemetry.io/otel/sdk
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-27 18:05:45 +00:00
Xav PaiceandSalah Al Saleh 4a84e26f21 Update dependabot.yml (#1494)
* Update dependabot.yml

* update dependabot.yml

* add another label

---------

Co-authored-by: Salah Al Saleh <sg.alsaleh@gmail.com>
2024-02-27 15:44:07 +00:00
Salah Al Saleh 2eb3aa9883 Add delay between approving and merging PR in the automated PRs manager (#1493) 2024-02-28 03:06:31 +13:00
dependabot[bot]andlnx01 ffd357c1e8 chore(deps): bump the go_modules group across 2 directories with 1 update (#1492)
Bumps the go_modules group with 1 update in the / directory: [helm.sh/helm/v3](https://github.com/helm/helm).


Updates `helm.sh/helm/v3` from 3.14.1 to 3.14.2
- [Release notes](https://github.com/helm/helm/releases)
- [Commits](https://github.com/helm/helm/compare/v3.14.1...v3.14.2)

---
updated-dependencies:
- dependency-name: helm.sh/helm/v3
  dependency-type: direct:production
  dependency-group: go_modules-security-group
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-27 06:05:54 +00:00
Salah Al Saleh 09287f624f Fix workflow name in automated PRs manager (#1491) 2024-02-26 15:16:39 -08:00
dependabot[bot]andlnx01 cd7f2dc74d chore(deps): bump helm.sh/helm/v3 from 3.14.1 to 3.14.2 in /examples/sdk/helm-template (#1490)
chore(deps): bump helm.sh/helm/v3 in /examples/sdk/helm-template

Bumps [helm.sh/helm/v3](https://github.com/helm/helm) from 3.14.1 to 3.14.2.
- [Release notes](https://github.com/helm/helm/releases)
- [Commits](https://github.com/helm/helm/compare/v3.14.1...v3.14.2)

---
updated-dependencies:
- dependency-name: helm.sh/helm/v3
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-26 22:41:19 +00:00
Salah Al Saleh 8132936e3e Fix automated PRs manager workflow (#1489)
* Fix automated PRs manager workflow
2024-02-26 14:30:21 -08:00
Xav PaiceandSalah Al Saleh b49d1050c9 feat: add dependabot auto merge (#1473)
* feat: add dependabot auto merge & grouping

Adds grouping for Dependabot PRs, meaning we no longer need to manually group PRs that fail tests due to incompatible groups.

Adds auto-merge of Dependabot PRs when they pass all tests.

* roll back dependabot label changes

* use secrets.GITHUB_TOKEN for automated PRs from Dependabot

* Automerge Dependabot PRS, use REPLICATED_GH_PAT for secret

* amend and simplify auto-dependabot job

* simplify PR jobs

* remove CODEOWNER ownership for go.mod

* Update .github/workflows/automated-prs-manager.yaml

Co-authored-by: Salah Al Saleh <sg.alsaleh@gmail.com>

---------

Co-authored-by: Salah Al Saleh <sg.alsaleh@gmail.com>
2024-02-23 12:28:39 +13:00
Xav Paice 27f867bd4e Update dependabot.yml (#1482) 2024-02-22 19:33:50 +13:00
Xav Paice f4d2cfb749 update Helm example for CVE (#1481) 2024-02-22 13:56:19 +13:00
dependabot[bot]andlnx01 8620e001d7 chore(deps): bump the security group with 16 updates (#1478)
Bumps the security group with 16 updates:

| Package | From | To |
| --- | --- | --- |
| [github.com/containers/image/v5](https://github.com/containers/image) | `5.29.0` | `5.29.2` |
| [github.com/google/uuid](https://github.com/google/uuid) | `1.4.0` | `1.6.0` |
| [github.com/shirou/gopsutil/v3](https://github.com/shirou/gopsutil) | `3.23.12` | `3.24.1` |
| [github.com/vmware-tanzu/velero](https://github.com/vmware-tanzu/velero) | `1.10.3` | `1.13.0` |
| [go.opentelemetry.io/otel](https://github.com/open-telemetry/opentelemetry-go) | `1.23.0` | `1.23.1` |
| [go.opentelemetry.io/otel/sdk](https://github.com/open-telemetry/opentelemetry-go) | `1.23.0` | `1.23.1` |
| [k8s.io/api](https://github.com/kubernetes/api) | `0.29.1` | `0.29.2` |
| [k8s.io/apiextensions-apiserver](https://github.com/kubernetes/apiextensions-apiserver) | `0.29.0` | `0.29.2` |
| [k8s.io/apimachinery](https://github.com/kubernetes/apimachinery) | `0.29.1` | `0.29.2` |
| [k8s.io/apiserver](https://github.com/kubernetes/apiserver) | `0.29.0` | `0.29.2` |
| [k8s.io/cli-runtime](https://github.com/kubernetes/cli-runtime) | `0.29.1` | `0.29.2` |
| [k8s.io/client-go](https://github.com/kubernetes/client-go) | `0.29.1` | `0.29.2` |
| [sigs.k8s.io/controller-runtime](https://github.com/kubernetes-sigs/controller-runtime) | `0.17.0` | `0.17.2` |
| [golang.org/x/net](https://github.com/golang/net) | `0.19.0` | `0.21.0` |
| [helm.sh/helm/v3](https://github.com/helm/helm) | `3.14.0` | `3.14.1` |
| [k8s.io/metrics](https://github.com/kubernetes/metrics) | `0.29.0` | `0.29.2` |


Updates `github.com/containers/image/v5` from 5.29.0 to 5.29.2
- [Release notes](https://github.com/containers/image/releases)
- [Commits](https://github.com/containers/image/compare/v5.29.0...v5.29.2)

Updates `github.com/google/uuid` from 1.4.0 to 1.6.0
- [Release notes](https://github.com/google/uuid/releases)
- [Changelog](https://github.com/google/uuid/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/uuid/compare/v1.4.0...v1.6.0)

Updates `github.com/shirou/gopsutil/v3` from 3.23.12 to 3.24.1
- [Release notes](https://github.com/shirou/gopsutil/releases)
- [Commits](https://github.com/shirou/gopsutil/compare/v3.23.12...v3.24.1)

Updates `github.com/vmware-tanzu/velero` from 1.10.3 to 1.13.0
- [Release notes](https://github.com/vmware-tanzu/velero/releases)
- [Changelog](https://github.com/vmware-tanzu/velero/blob/main/CHANGELOG.md)
- [Commits](https://github.com/vmware-tanzu/velero/compare/v1.10.3...v1.13.0)

Updates `go.opentelemetry.io/otel` from 1.23.0 to 1.23.1
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.23.0...v1.23.1)

Updates `go.opentelemetry.io/otel/sdk` from 1.23.0 to 1.23.1
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.23.0...v1.23.1)

Updates `k8s.io/api` from 0.29.1 to 0.29.2
- [Commits](https://github.com/kubernetes/api/compare/v0.29.1...v0.29.2)

Updates `k8s.io/apiextensions-apiserver` from 0.29.0 to 0.29.2
- [Release notes](https://github.com/kubernetes/apiextensions-apiserver/releases)
- [Commits](https://github.com/kubernetes/apiextensions-apiserver/compare/v0.29.0...v0.29.2)

Updates `k8s.io/apimachinery` from 0.29.1 to 0.29.2
- [Commits](https://github.com/kubernetes/apimachinery/compare/v0.29.1...v0.29.2)

Updates `k8s.io/apiserver` from 0.29.0 to 0.29.2
- [Commits](https://github.com/kubernetes/apiserver/compare/v0.29.0...v0.29.2)

Updates `k8s.io/cli-runtime` from 0.29.1 to 0.29.2
- [Commits](https://github.com/kubernetes/cli-runtime/compare/v0.29.1...v0.29.2)

Updates `k8s.io/client-go` from 0.29.1 to 0.29.2
- [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kubernetes/client-go/compare/v0.29.1...v0.29.2)

Updates `sigs.k8s.io/controller-runtime` from 0.17.0 to 0.17.2
- [Release notes](https://github.com/kubernetes-sigs/controller-runtime/releases)
- [Changelog](https://github.com/kubernetes-sigs/controller-runtime/blob/main/RELEASE.md)
- [Commits](https://github.com/kubernetes-sigs/controller-runtime/compare/v0.17.0...v0.17.2)

Updates `golang.org/x/net` from 0.19.0 to 0.21.0
- [Commits](https://github.com/golang/net/compare/v0.19.0...v0.21.0)

Updates `helm.sh/helm/v3` from 3.14.0 to 3.14.1
- [Release notes](https://github.com/helm/helm/releases)
- [Commits](https://github.com/helm/helm/compare/v3.14.0...v3.14.1)

Updates `k8s.io/metrics` from 0.29.0 to 0.29.2
- [Commits](https://github.com/kubernetes/metrics/compare/v0.29.0...v0.29.2)

---
updated-dependencies:
- dependency-name: github.com/containers/image/v5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: github.com/google/uuid
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: github.com/shirou/gopsutil/v3
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: github.com/vmware-tanzu/velero
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: go.opentelemetry.io/otel
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: go.opentelemetry.io/otel/sdk
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/api
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/apiextensions-apiserver
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/apimachinery
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/apiserver
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/cli-runtime
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/client-go
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: sigs.k8s.io/controller-runtime
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: helm.sh/helm/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/metrics
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-20 16:23:56 +13:00
dependabot[bot]andlnx01 bb9a2931a1 chore(deps): bump github.com/opencontainers/image-spec from 1.1.0-rc6 to 1.1.0 (#1479)
chore(deps): bump github.com/opencontainers/image-spec

Bumps [github.com/opencontainers/image-spec](https://github.com/opencontainers/image-spec) from 1.1.0-rc6 to 1.1.0.
- [Release notes](https://github.com/opencontainers/image-spec/releases)
- [Changelog](https://github.com/opencontainers/image-spec/blob/main/RELEASES.md)
- [Commits](https://github.com/opencontainers/image-spec/compare/v1.1.0-rc6...v1.1.0)

---
updated-dependencies:
- dependency-name: github.com/opencontainers/image-spec
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-20 16:23:10 +13:00
Xav Paice 7c6788c0c5 Update dependabot.yml (#1477) 2024-02-20 15:42:17 +13:00
Ethan Mosbaugh e24ca642aa feat: sonobuoy collector (#1469) 2024-02-16 06:56:15 -08:00
dependabot[bot]andlnx01 7dc9d6dfe4 chore(deps): bump github.com/fatih/color from 1.15.0 to 1.16.0 (#1467)
Bumps [github.com/fatih/color](https://github.com/fatih/color) from 1.15.0 to 1.16.0.
- [Release notes](https://github.com/fatih/color/releases)
- [Commits](https://github.com/fatih/color/compare/v1.15.0...v1.16.0)

---
updated-dependencies:
- dependency-name: github.com/fatih/color
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-15 11:09:12 +00:00
dependabot[bot]andlnx01 118b2edc0a chore(deps): bump golang.org/x/mod from 0.14.0 to 0.15.0 (#1468)
Bumps [golang.org/x/mod](https://github.com/golang/mod) from 0.14.0 to 0.15.0.
- [Commits](https://github.com/golang/mod/compare/v0.14.0...v0.15.0)

---
updated-dependencies:
- dependency-name: golang.org/x/mod
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-15 11:07:30 +00:00
dependabot[bot]andlnx01 84d51481da chore(deps): bump oras.land/oras-go from 1.2.4 to 1.2.5 (#1464)
Bumps [oras.land/oras-go](https://github.com/oras-project/oras-go) from 1.2.4 to 1.2.5.
- [Release notes](https://github.com/oras-project/oras-go/releases)
- [Commits](https://github.com/oras-project/oras-go/compare/v1.2.4...v1.2.5)

---
updated-dependencies:
- dependency-name: oras.land/oras-go
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-15 10:47:46 +00:00
Evans Mungai fad7a26156 fix: improve flaky goldpinger test (#1463)
We do not need to check if goldpinger pinged or not. At times it would have successful pings that lead to test failures. Its enough to just check that we have analysis results
2024-02-09 16:33:52 +00:00
Gerard Nguyen 772d867093 update correct K8S API group for batch and policy (#1461) 2024-02-09 08:17:55 +13:00
Gerard Nguyen 5daf6d6c89 Feat: new collector run-daemonset (#1460)
* feat: new collector run-daemonset
2024-02-09 08:16:32 +13:00
Xav Paice 8b491b5702 Downgrade Velero to v1.10 (#1462)
In order to be compatible with KOTS, downgrade Velero to 1.10.

This removes some features from the Velero collector, but unblocks KOTS from being able
to import Troubleshoot.

We should be wary of updating Velero in the future to prevent this recurring.

sc-98475
2024-02-09 08:13:26 +13:00
18efea6616 chore(deps): bump go.opentelemetry.io/otel from 1.19.0 to 1.23.0 (#1459)
* chore(deps): bump go.opentelemetry.io/otel from 1.19.0 to 1.23.0

Bumps [go.opentelemetry.io/otel](https://github.com/open-telemetry/opentelemetry-go) from 1.19.0 to 1.23.0.
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.19.0...v1.23.0)

---
updated-dependencies:
- dependency-name: go.opentelemetry.io/otel
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* bump go.opentelemetry.io/otel/sdk

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Xav Paice <xav@replicated.com>
2024-02-07 11:35:41 +00:00
dependabot[bot]andlnx01 48fc8b2e84 chore(deps): bump k8s.io/klog/v2 from 2.110.1 to 2.120.1 (#1453)
Bumps [k8s.io/klog/v2](https://github.com/kubernetes/klog) from 2.110.1 to 2.120.1.
- [Release notes](https://github.com/kubernetes/klog/releases)
- [Changelog](https://github.com/kubernetes/klog/blob/main/RELEASE.md)
- [Commits](https://github.com/kubernetes/klog/compare/v2.110.1...v2.120.1)

---
updated-dependencies:
- dependency-name: k8s.io/klog/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-07 11:35:06 +00:00
Evans Mungai e2adfa3774 fix: Correct selector used to find installer specs when redacting (#1456) 2024-02-07 10:36:15 +00:00
Xav Paice 41134ca621 Revert "chore(deps): bump github.com/vmware-tanzu/velero from 1.12.0 to 1.13.0" (#1458)
Revert "chore(deps): bump github.com/vmware-tanzu/velero from 1.12.0 to 1.13.…"

This reverts commit d4c1e9cc04.
2024-02-07 13:21:01 +13:00
dependabot[bot]andlnx01 05a852d68c chore(deps): bump github.com/jackc/pgx/v5 from 5.5.2 to 5.5.3 (#1452)
Bumps [github.com/jackc/pgx/v5](https://github.com/jackc/pgx) from 5.5.2 to 5.5.3.
- [Changelog](https://github.com/jackc/pgx/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jackc/pgx/compare/v5.5.2...v5.5.3)

---
updated-dependencies:
- dependency-name: github.com/jackc/pgx/v5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-06 20:41:43 +13:00
dependabot[bot]andlnx01 90d04b1f7d chore(deps): bump github.com/opencontainers/image-spec from 1.1.0-rc5 to 1.1.0-rc6 (#1454)
chore(deps): bump github.com/opencontainers/image-spec

Bumps [github.com/opencontainers/image-spec](https://github.com/opencontainers/image-spec) from 1.1.0-rc5 to 1.1.0-rc6.
- [Release notes](https://github.com/opencontainers/image-spec/releases)
- [Changelog](https://github.com/opencontainers/image-spec/blob/main/RELEASES.md)
- [Commits](https://github.com/opencontainers/image-spec/compare/v1.1.0-rc5...v1.1.0-rc6)

---
updated-dependencies:
- dependency-name: github.com/opencontainers/image-spec
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-06 20:41:13 +13:00
dependabot[bot]andlnx01 de0a2c631c chore(deps): bump helm.sh/helm/v3 from 3.13.3 to 3.14.0 (#1451)
Bumps [helm.sh/helm/v3](https://github.com/helm/helm) from 3.13.3 to 3.14.0.
- [Release notes](https://github.com/helm/helm/releases)
- [Commits](https://github.com/helm/helm/compare/v3.13.3...v3.14.0)

---
updated-dependencies:
- dependency-name: helm.sh/helm/v3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-06 20:40:48 +13:00
Evans Mungai 2def517d39 chore: additional ceph collector commands (#1450)
* Collect text representations of the ceph data which are easier to read
* Collect ceph df command output
2024-02-06 10:04:25 +13:00
Xav PaiceandEvans Mungai fe6b1c7448 Add workaround for EKS version string (#1449)
* Add workaround for EKS version string

The EKS version string returned is not semver compliant.  To work around this, we remove
the suffix for version strings that contain -eks-.

Fixes #1441

* Add parsing version test cases

* Rename function

---------

Co-authored-by: Evans Mungai <evans@replicated.com>
2024-02-06 10:04:01 +13:00
Xav Paice 710366c8e5 bump containerd to patch for CVE-2024-21626 (#1445) 2024-02-01 17:16:51 +13:00
dependabot[bot]andlnx01 96529106c7 chore(deps): bump github.com/opencontainers/runc from 1.1.10 to 1.1.12 (#1444)
Bumps [github.com/opencontainers/runc](https://github.com/opencontainers/runc) from 1.1.10 to 1.1.12.
- [Release notes](https://github.com/opencontainers/runc/releases)
- [Changelog](https://github.com/opencontainers/runc/blob/v1.1.12/CHANGELOG.md)
- [Commits](https://github.com/opencontainers/runc/compare/v1.1.10...v1.1.12)

---
updated-dependencies:
- dependency-name: github.com/opencontainers/runc
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-01 14:43:58 +13:00
Gerard Nguyen 39b371991e feat: add timeout to run host collector (#1435)
* feat: add timeout to run host collector

* return error on invalid timeout

* return -1 on context deadline exceeded
2024-01-31 12:46:01 +00:00
dependabot[bot]andlnx01 d4c1e9cc04 chore(deps): bump github.com/vmware-tanzu/velero from 1.12.0 to 1.13.0 (#1437)
Bumps [github.com/vmware-tanzu/velero](https://github.com/vmware-tanzu/velero) from 1.12.0 to 1.13.0.
- [Release notes](https://github.com/vmware-tanzu/velero/releases)
- [Changelog](https://github.com/vmware-tanzu/velero/blob/main/CHANGELOG.md)
- [Commits](https://github.com/vmware-tanzu/velero/compare/v1.12.0...v1.13.0)

---
updated-dependencies:
- dependency-name: github.com/vmware-tanzu/velero
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-30 13:33:35 +00:00
dependabot[bot]andlnx01 70a0024a76 chore(deps): bump k8s.io/cli-runtime from 0.29.0 to 0.29.1 (#1439)
Bumps [k8s.io/cli-runtime](https://github.com/kubernetes/cli-runtime) from 0.29.0 to 0.29.1.
- [Commits](https://github.com/kubernetes/cli-runtime/compare/v0.29.0...v0.29.1)

---
updated-dependencies:
- dependency-name: k8s.io/cli-runtime
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-30 13:33:23 +00:00
dependabot[bot]andlnx01 62984cba40 chore(deps): bump github.com/hashicorp/go-getter from 1.7.2 to 1.7.3 (#1438)
Bumps [github.com/hashicorp/go-getter](https://github.com/hashicorp/go-getter) from 1.7.2 to 1.7.3.
- [Release notes](https://github.com/hashicorp/go-getter/releases)
- [Changelog](https://github.com/hashicorp/go-getter/blob/main/.goreleaser.yml)
- [Commits](https://github.com/hashicorp/go-getter/compare/v1.7.2...v1.7.3)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/go-getter
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-30 12:59:29 +00:00
Diamon WigginsandEvans Mungai 1447e18c56 feat: Allow templating of outcome messages for the JSON/YAML compare analyzers (#1432)
* feat: allow templating of the outcome message for the JSON and YAML Compare analyzers

* Update pkg/analyze/json_compare.go

Co-authored-by: Evans Mungai <evans@replicated.com>
2024-01-26 10:56:57 -05:00
Evans Mungai 37a5cce8ce chore: minor updates to docs and Makefile (#1433)
* Deprecate old Makefile targets
* Name Makefile targets to point to files they 'make' as per convention
* Update the contributing doc
* Update CLI docs left behind
2024-01-25 18:55:51 +00:00
dependabot[bot]andlnx01 80de5e3d12 chore(deps): bump github.com/spf13/cobra from 1.7.0 to 1.8.0 (#1422)
Bumps [github.com/spf13/cobra](https://github.com/spf13/cobra) from 1.7.0 to 1.8.0.
- [Release notes](https://github.com/spf13/cobra/releases)
- [Commits](https://github.com/spf13/cobra/compare/v1.7.0...v1.8.0)

---
updated-dependencies:
- dependency-name: github.com/spf13/cobra
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-23 19:05:54 +13:00
dependabot[bot]andlnx01 c1eddca1e5 chore(deps): bump github.com/gorilla/handlers from 1.5.1 to 1.5.2 (#1428)
Bumps [github.com/gorilla/handlers](https://github.com/gorilla/handlers) from 1.5.1 to 1.5.2.
- [Release notes](https://github.com/gorilla/handlers/releases)
- [Commits](https://github.com/gorilla/handlers/compare/v1.5.1...v1.5.2)

---
updated-dependencies:
- dependency-name: github.com/gorilla/handlers
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-23 15:31:01 +13:00
dependabot[bot]andlnx01 19a04dc24e chore(deps): bump sigs.k8s.io/controller-runtime from 0.16.3 to 0.17.0 (#1429)
Bumps [sigs.k8s.io/controller-runtime](https://github.com/kubernetes-sigs/controller-runtime) from 0.16.3 to 0.17.0.
- [Release notes](https://github.com/kubernetes-sigs/controller-runtime/releases)
- [Changelog](https://github.com/kubernetes-sigs/controller-runtime/blob/main/RELEASE.md)
- [Commits](https://github.com/kubernetes-sigs/controller-runtime/compare/v0.16.3...v0.17.0)

---
updated-dependencies:
- dependency-name: sigs.k8s.io/controller-runtime
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-23 15:30:10 +13:00
dependabot[bot]andlnx01 5d51207f4d chore(deps): bump sigs.k8s.io/yaml from 1.3.0 to 1.4.0 (#1430)
Bumps [sigs.k8s.io/yaml](https://github.com/kubernetes-sigs/yaml) from 1.3.0 to 1.4.0.
- [Release notes](https://github.com/kubernetes-sigs/yaml/releases)
- [Changelog](https://github.com/kubernetes-sigs/yaml/blob/master/RELEASE.md)
- [Commits](https://github.com/kubernetes-sigs/yaml/compare/v1.3.0...v1.4.0)

---
updated-dependencies:
- dependency-name: sigs.k8s.io/yaml
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-23 15:28:29 +13:00
dependabot[bot]andlnx01 8d727ea31f chore(deps): bump github.com/jackc/pgx/v5 from 5.4.3 to 5.5.2 (#1426)
Bumps [github.com/jackc/pgx/v5](https://github.com/jackc/pgx) from 5.4.3 to 5.5.2.
- [Changelog](https://github.com/jackc/pgx/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jackc/pgx/compare/v5.4.3...v5.5.2)

---
updated-dependencies:
- dependency-name: github.com/jackc/pgx/v5
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-18 12:51:45 +00:00
dependabot[bot]andlnx01 b46f89af7f chore(deps): bump github.com/shirou/gopsutil/v3 from 3.23.9 to 3.23.12 (#1423)
Bumps [github.com/shirou/gopsutil/v3](https://github.com/shirou/gopsutil) from 3.23.9 to 3.23.12.
- [Release notes](https://github.com/shirou/gopsutil/releases)
- [Commits](https://github.com/shirou/gopsutil/compare/v3.23.9...v3.23.12)

---
updated-dependencies:
- dependency-name: github.com/shirou/gopsutil/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-18 12:17:29 +00:00
dependabot[bot]andlnx01 5ad108fab6 chore(deps): bump github.com/spf13/viper from 1.17.0 to 1.18.2 (#1421)
Bumps [github.com/spf13/viper](https://github.com/spf13/viper) from 1.17.0 to 1.18.2.
- [Release notes](https://github.com/spf13/viper/releases)
- [Commits](https://github.com/spf13/viper/compare/v1.17.0...v1.18.2)

---
updated-dependencies:
- dependency-name: github.com/spf13/viper
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-18 12:08:40 +00:00
Akash Shrivastava 361e12e691 feat: [ISSUE-1401]: Added helm get values option in Helm collector (#1402)
* feat: [ISSUE-1401]: Added helm get values option in Helm collector

Signed-off-by: Akash Shrivastava <akash.shrivastava@harness.io>

* Made changes in error handling

Signed-off-by: Akash Shrivastava <akash.shrivastava@harness.io>

* feat: [ISSUE-1401]: Added test cases and fixes

Signed-off-by: Akash Shrivastava <akash.shrivastava@harness.io>

* fixed test case

Signed-off-by: Akash Shrivastava <akash.shrivastava@harness.io>

---------

Signed-off-by: Akash Shrivastava <akash.shrivastava@harness.io>
2024-01-16 19:12:43 +00:00
Xav Paice e542f4fd0a bump k8s.io packages to v0.29.0 (#1419)
* bump k8s.io packages to v0.29.0

* update Go to 1.21

* update schemas
2024-01-08 17:24:41 +00:00
Evans Mungai e4363a1e50 fix (supportbundle): Add default collectors when expected (#1418)
* fix (supportbundle): Add default collectors when expected

* Remove unnecessary change

* Add default collectors to a empty spec

* Add more tests
2024-01-08 11:32:04 +00:00
dependabot[bot]andlnx01 b5996d06ba chore(deps): bump github.com/go-logr/logr from 1.2.4 to 1.4.1 (#1412)
Bumps [github.com/go-logr/logr](https://github.com/go-logr/logr) from 1.2.4 to 1.4.1.
- [Release notes](https://github.com/go-logr/logr/releases)
- [Changelog](https://github.com/go-logr/logr/blob/master/CHANGELOG.md)
- [Commits](https://github.com/go-logr/logr/compare/v1.2.4...v1.4.1)

---
updated-dependencies:
- dependency-name: github.com/go-logr/logr
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-02 16:05:18 +00:00
dependabot[bot]andlnx01 b1b6299ed5 chore(deps): bump golang.org/x/mod from 0.13.0 to 0.14.0 (#1414)
Bumps [golang.org/x/mod](https://github.com/golang/mod) from 0.13.0 to 0.14.0.
- [Commits](https://github.com/golang/mod/compare/v0.13.0...v0.14.0)

---
updated-dependencies:
- dependency-name: golang.org/x/mod
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-02 16:04:29 +00:00
dependabot[bot]andlnx01 7681cc249c chore(deps): bump sigs.k8s.io/controller-runtime from 0.16.2 to 0.16.3 (#1416)
Bumps [sigs.k8s.io/controller-runtime](https://github.com/kubernetes-sigs/controller-runtime) from 0.16.2 to 0.16.3.
- [Release notes](https://github.com/kubernetes-sigs/controller-runtime/releases)
- [Changelog](https://github.com/kubernetes-sigs/controller-runtime/blob/main/RELEASE.md)
- [Commits](https://github.com/kubernetes-sigs/controller-runtime/compare/v0.16.2...v0.16.3)

---
updated-dependencies:
- dependency-name: sigs.k8s.io/controller-runtime
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-02 16:03:33 +00:00
dependabot[bot]andlnx01 cad5e8179c chore(deps): bump helm.sh/helm/v3 from 3.12.3 to 3.13.3 (#1410)
Bumps [helm.sh/helm/v3](https://github.com/helm/helm) from 3.12.3 to 3.13.3.
- [Release notes](https://github.com/helm/helm/releases)
- [Commits](https://github.com/helm/helm/compare/v3.12.3...v3.13.3)

---
updated-dependencies:
- dependency-name: helm.sh/helm/v3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-29 08:03:59 +13:00
Andrew Laveryandlnx01 4c77bcb7cc Update containers/image, oras-go, and docker (#1411)
* chore(deps): bump github.com/containers/image/v5 from 5.25.0 to 5.29.0

Bumps [github.com/containers/image/v5](https://github.com/containers/image) from 5.25.0 to 5.29.0.
- [Release notes](https://github.com/containers/image/releases)
- [Commits](https://github.com/containers/image/compare/v5.25.0...v5.29.0)

---
updated-dependencies:
- dependency-name: github.com/containers/image/v5
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* regenerate files

* bump oras-go

* changes from 'make test'

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-28 13:31:05 -05:00
Xav Paice 534931600b bump github actions/download-artifact (#1409) 2023-12-20 16:38:14 +13:00
dependabot[bot]andlnx01 acaa2edd30 chore(deps): bump github.com/containerd/containerd from 1.7.0 to 1.7.11 (#1408)
Bumps [github.com/containerd/containerd](https://github.com/containerd/containerd) from 1.7.0 to 1.7.11.
- [Release notes](https://github.com/containerd/containerd/releases)
- [Changelog](https://github.com/containerd/containerd/blob/main/RELEASES.md)
- [Commits](https://github.com/containerd/containerd/compare/v1.7.0...v1.7.11)

---
updated-dependencies:
- dependency-name: github.com/containerd/containerd
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-20 16:24:27 +13:00
Evans Mungai a86b5c4441 chore(preflight): Better error message when not results found (#1397)
code(preflight): Better error message when not results found
2023-12-20 16:10:47 +13:00
dependabot[bot]andlnx01 bd275dfbab chore(deps): bump github/codeql-action from 2 to 3 (#1403)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2 to 3.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-20 16:09:57 +13:00
dependabot[bot]andlnx01 7093fa0865 chore(deps): bump golang.org/x/crypto from 0.14.0 to 0.17.0 in /examples/sdk/helm-template (#1406)
chore(deps): bump golang.org/x/crypto in /examples/sdk/helm-template

Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.14.0 to 0.17.0.
- [Commits](https://github.com/golang/crypto/compare/v0.14.0...v0.17.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-20 16:09:20 +13:00
Evans Mungai 3012b870bd fix: flaky e2e test (#1400) 2023-12-20 16:07:30 +13:00
dependabot[bot]andlnx01 f44a3d3986 chore(deps): bump golang.org/x/crypto from 0.14.0 to 0.17.0 (#1407)
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.14.0 to 0.17.0.
- [Commits](https://github.com/golang/crypto/compare/v0.14.0...v0.17.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-20 16:06:33 +13:00
Evans Mungai 53113c0170 feat: goldpinger collector and analyser (#1398)
* feat: goldpinger analyser

Analyser to generate a report from goldpinger results

* Add goldpinger testdata

* Goldpinger collector

* Improvements after running tests

* More minor updates after further testing

* Better error message if a container fails to start

* A few more updates

* Add goldpinger e2e test

* Update schemas

* Clean up help installs in e2e tests

* Add resource limits to goldpinger pods

* Some minor improvements

* Some more changes noted when writing docs

* Update schemas

* A few more updates when testing with kURL

* Log goldpinger tests

* Tests before exit code
2023-12-12 11:02:41 +00:00
dependabot[bot]andlnx01 b0907d7139 chore(deps): bump actions/setup-go from 4 to 5 (#1399)
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 4 to 5.
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/setup-go
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-12 10:31:47 +00:00
Evans Mungai fef12be8f1 fix(support-bundle): add Replicated user-agent header to the correct URLs (#1396)
fix(support-bundle): correct user-agent bevahiour

Only kots.io requires a user agent when downloading troubleshoot specs
2023-12-01 16:29:43 +00:00
Evans Mungai e5e26eea14 fix(support-bundle): default in-cluster collectors in host support bundle (#1394)
* fix(support-bundle): default in-cluster collectors in host support bundle

Ensure cluster-resources and cluster-info collectors are present only
when a support bundle spec contains in-cluster collectors.

* Various improvements

* Improve error messages
* Util function appending elements to a nil slice that allows adding
  specs to an empty slice of collectors/analysers/redactors

* Fix failing test
2023-11-27 18:33:02 +00:00
Evans Mungai d4623d9404 fix(collector): Let pgx library parse TLS parameters (#1390)
* fix(collector): Let pgx library parse TLS parameters

This allows the collector to respect the sslmode parameters

Fix: #1163

* Add comment

* Improve postgres collector test
2023-11-16 12:51:43 +00:00
Weiyanli Chen(York)andEvans Mungai bc4856869e fix: missing omitempty on 2 of the new fields (#1389)
* fix: missing omitempty on 2 of the new fields

* fix: Rename TS_WORKSPACE_DIR to TS_OUTPUT_DIR

---------

Co-authored-by: Evans Mungai <evans@replicated.com>
2023-11-09 13:25:11 +00:00
Weiyanli Chen(York)andEvans Mungai f6373f3e36 feat: save host run file output (#1376)
* feat: save cmd run output

* chore: schema changes

* chore: example hostCollector

* chore: add log messages to key actions

* fix: correctly inherit all parent env by default

* chore: do not save input file

the user invokes the input already got the input but those content could be sensitive to another user who received this bundle

* test: unit test for host run

* revert: "chore: do not save input file"

This reverts commit 6af77ad1ce.

that commit is wrong

* chore: fix log msg and example yaml

* Ensure child cmd runs in its own working dir

* Check filename for slashes not content

* Update logging

* Add using relative path files as commands

---------

Co-authored-by: Evans Mungai <evans@replicated.com>
2023-11-08 13:49:46 +00:00
Archit Sharma 7038da85b1 Velero analyzer (#1366)
* feat: add velero analyzer (#806)

  * updated schema
  * analyzer without collector
  * tests
  * covers deprecated Restic repository type
  * velero version from deployment image to check deprecated type
  * read for both velero pod kinds (velero*, node-agent*)

---------

Signed-off-by: Archit Sharma <archit@pm.me>
2023-11-03 18:41:17 +05:30
Jason McCampbell a7bb9ea31e Add support for Oracle OKE environment (#1387) 2023-11-02 17:16:18 +13:00
Diamon WigginsandEvans Mungai 08c3fcf3df Gracefully handle unreachable URIs in loadSupportBundleSpecsFromURIs (#1383)
* gracefully handle unreachable URIs in loadSupportBundleSpecsFromURIs

* let caller decide how to handle the error

* fix klog import

* Add a test to ensure failing to load uri does not error

---------

Co-authored-by: Evans Mungai <evans@replicated.com>
2023-10-27 14:48:09 +01:00
dependabot[bot]andlnx01 1d2c1191e2 chore(deps): bump google.golang.org/grpc from 1.58.2 to 1.58.3 (#1380)
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.58.2 to 1.58.3.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.58.2...v1.58.3)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-27 11:06:39 +01:00
dependabot[bot]andlnx01 66e070a07d chore(deps): bump go.opentelemetry.io/otel/sdk from 1.18.0 to 1.19.0 (#1378)
Bumps [go.opentelemetry.io/otel/sdk](https://github.com/open-telemetry/opentelemetry-go) from 1.18.0 to 1.19.0.
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.18.0...v1.19.0)

---
updated-dependencies:
- dependency-name: go.opentelemetry.io/otel/sdk
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-24 10:03:45 +10:00
dependabot[bot]andlnx01 7528c57e83 chore(deps): bump golang.org/x/sync from 0.3.0 to 0.4.0 (#1373)
Bumps [golang.org/x/sync](https://github.com/golang/sync) from 0.3.0 to 0.4.0.
- [Commits](https://github.com/golang/sync/compare/v0.3.0...v0.4.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sync
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-19 16:14:39 +01:00
187 changed files with 74420 additions and 16026 deletions
+5 -1
View File
@@ -14,4 +14,8 @@
## RULES
* @replicatedhq/troubleshoot
*.md @replicatedhq/cre
*.md @replicatedhq/cre
go.mod
go.sum
/examples/sdk/helm-template/go.mod
/examples/sdk/helm-template/go.sum
+21 -3
View File
@@ -10,10 +10,28 @@ updates:
labels:
- "dependencies"
- "go"
- "type::chore"
- "type::security"
schedule:
interval: "weekly"
groups:
security:
update-types:
- "patch"
- "minor"
- package-ecosystem: "gomod" # See documentation for possible values
directory: "/examples/sdk/helm-template" # Location of package manifests
labels:
- "dependencies"
- "go"
- "type::security"
schedule:
interval: "weekly"
groups:
security:
update-types:
- "patch"
- "minor"
# Maintain dependencies for GitHub Actions
- package-ecosystem: "github-actions"
# Workflow files stored in the
@@ -22,6 +40,6 @@ updates:
labels:
- "dependencies"
- "github-actions"
- "type::chore"
- "type::security"
schedule:
interval: "weekly"
@@ -0,0 +1,97 @@
name: Automated PRs Manager
on:
schedule:
- cron: "0 */6 * * *" # every 6 hours
workflow_dispatch: {}
jobs:
list-prs:
runs-on: ubuntu-latest
outputs:
prs: ${{ steps.list-prs.outputs.prs }}
env:
GH_TOKEN: ${{ secrets.REPLICATED_GH_PAT }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: List PRs
id: list-prs
run: |
set -euo pipefail
# list prs that are less than 24h old and exclude prs from forks
dependabot_prs=$(
gh pr list \
--author 'dependabot[bot]' \
--json url,createdAt,headRefName,headRepository,headRepositoryOwner \
-q '.[] | select((.createdAt | fromdateiso8601 > now - 24*60*60) and .headRepositoryOwner.login == "replicatedhq" and .headRepository.name == "troubleshoot")'
)
prs=$(echo "$dependabot_prs" | jq -sc '. | unique')
echo "prs=$prs" >> "$GITHUB_OUTPUT"
process-prs:
needs: list-prs
runs-on: ubuntu-latest
if: needs.list-prs.outputs.prs != '[]'
strategy:
matrix:
pr: ${{ fromJson(needs.list-prs.outputs.prs) }}
fail-fast: false
max-parallel: 1
env:
GH_TOKEN: ${{ secrets.REPLICATED_GH_PAT }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ matrix.pr.headRefName }}
- name: Process PR
run: |
set -euo pipefail
echo "Ensuring required labels..."
gh pr edit "${{ matrix.pr.url }}" --add-label "type::security"
echo "Checking status of tests..."
run_id=$(gh run list --branch "${{ matrix.pr.headRefName }}" --workflow build-test-deploy --limit 1 --json databaseId -q '.[0].databaseId')
# If there are still pending jobs, skip.
num_of_pending_jobs=$(gh run view "$run_id" --json jobs -q '.jobs[] | select(.conclusion == "") | .name' | wc -l)
if [ "$num_of_pending_jobs" -gt 0 ]; then
echo "There are still pending jobs. Skipping."
exit 0
fi
# If all checks passed, approve and merge.
if gh run view "$run_id" --json jobs -q '.jobs[] | select(.name == "validate-success") | .conclusion' | grep -q "success"; then
if gh pr checks "${{ matrix.pr.url }}"; then
echo "All tests passed. Approving and merging."
echo -e "LGTM :thumbsup: \n\nThis PR was automatically approved and merged by the [automated-prs-manager](https://github.com/replicatedhq/troubleshoot/blob/main/.github/workflows/automated-prs-manager.yaml) GitHub action" > body.txt
gh pr review --approve "${{ matrix.pr.url }}" --body-file body.txt
sleep 10
gh pr merge --auto --squash "${{ matrix.pr.url }}"
exit 0
else
echo "Some checks did not pass. Skipping."
exit 0
fi
fi
# If more than half of the jobs are successful, re-run the failed jobs.
num_of_jobs=$(gh run view "$run_id" --json jobs -q '.jobs[].name ' | wc -l)
num_of_successful_jobs=$(gh run view "$run_id" --json jobs -q '.jobs[] | select(.conclusion == "success") | .name' | wc -l)
if [ "$num_of_successful_jobs" -gt $((num_of_jobs / 2)) ]; then
echo "More than half of the jobs are successful. Re-running failed jobs."
gh run rerun "$run_id" --failed
exit 0
fi
echo "Less than half of the jobs are successful. Skipping."
+69 -30
View File
@@ -1,3 +1,5 @@
name: build-test-deploy
on:
pull_request:
types:
@@ -28,9 +30,9 @@ jobs:
test:
runs-on: ubuntu-20.04
steps:
- uses: actions/setup-go@v4
- uses: actions/setup-go@v5
with:
go-version: "1.20"
go-version: "1.22"
- name: setup env
run: |
@@ -45,9 +47,9 @@ jobs:
test-integration:
runs-on: ubuntu-20.04
steps:
- uses: actions/setup-go@v4
- uses: actions/setup-go@v5
with:
go-version: "1.20"
go-version: "1.22"
- name: setup env
run: |
@@ -59,16 +61,16 @@ jobs:
- uses: replicatedhq/action-k3s@main
id: k3s
with:
version: v1.23.6-k3s1
version: v1.24.1-k3s1
- run: make test-integration
ensure-schemas-are-generated:
runs-on: ubuntu-latest
steps:
- uses: actions/setup-go@v4
- uses: actions/setup-go@v5
with:
go-version: "1.20"
go-version: "1.22"
- name: setup env
run: |
echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV
@@ -82,9 +84,9 @@ jobs:
compile-preflight:
runs-on: ubuntu-latest
steps:
- uses: actions/setup-go@v4
- uses: actions/setup-go@v5
with:
go-version: "1.20"
go-version: "1.22"
- name: setup env
run: |
echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV
@@ -92,7 +94,7 @@ jobs:
shell: bash
- uses: actions/checkout@v4
- run: make generate preflight
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: preflight
path: bin/preflight
@@ -106,7 +108,7 @@ jobs:
with:
version: v1.23.6-k3s1
- name: Download preflight binary
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: preflight
path: bin/
@@ -155,7 +157,7 @@ jobs:
with:
version: v1.23.6-k3s1
- name: Download preflight binary
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: preflight
path: bin/
@@ -171,9 +173,9 @@ jobs:
compile-supportbundle:
runs-on: ubuntu-latest
steps:
- uses: actions/setup-go@v4
- uses: actions/setup-go@v5
with:
go-version: "1.20"
go-version: "1.22"
- name: setup env
run: |
echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV
@@ -181,7 +183,7 @@ jobs:
shell: bash
- uses: actions/checkout@v4
- run: make generate support-bundle
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: support-bundle
path: bin/support-bundle
@@ -196,7 +198,7 @@ jobs:
with:
version: v1.23.6-k3s1
- name: Download support-bundle binary
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: support-bundle
path: bin/
@@ -215,7 +217,7 @@ jobs:
with:
version: v1.23.6-k3s1
- name: Download support bundle binary
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: support-bundle
path: bin/
@@ -226,9 +228,9 @@ jobs:
runs-on: ubuntu-latest
needs: compile-supportbundle
steps:
- uses: actions/setup-go@v4
- uses: actions/setup-go@v5
with:
go-version: "1.20"
go-version: "1.22"
- name: setup env
run: |
echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV
@@ -236,7 +238,7 @@ jobs:
shell: bash
- uses: actions/checkout@v4
- name: Download support bundle binary
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: support-bundle
path: bin/
@@ -246,9 +248,9 @@ jobs:
compile-collect:
runs-on: ubuntu-latest
steps:
- uses: actions/setup-go@v4
- uses: actions/setup-go@v5
with:
go-version: "1.20"
go-version: "1.22"
- name: setup env
run: |
echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV
@@ -256,7 +258,7 @@ jobs:
shell: bash
- uses: actions/checkout@v4
- run: make generate collect
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: collect
path: bin/collect
@@ -279,12 +281,12 @@ jobs:
with:
fetch-depth: 0
- uses: actions/setup-go@v4
- uses: actions/setup-go@v5
with:
go-version: "1.20"
go-version: "1.22"
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v5
uses: goreleaser/goreleaser-action@v6
with:
version: "v0.183.0"
args: build --rm-dist --snapshot --config deploy/.goreleaser.yaml --single-target
@@ -305,14 +307,14 @@ jobs:
with:
fetch-depth: 0
- uses: azure/docker-login@v1
- uses: azure/docker-login@v2
with:
username: ${{ secrets.DOCKERHUB_USER }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
- uses: actions/setup-go@v4
- uses: actions/setup-go@v5
with:
go-version: "1.20"
go-version: "1.22"
- uses: sigstore/cosign-installer@v3
with:
@@ -333,7 +335,7 @@ jobs:
COSIGN_KEY: ${{ secrets.COSIGN_KEY }}
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v5
uses: goreleaser/goreleaser-action@v6
with:
version: "v1.x" # Binary version to install
args: release --rm-dist --config deploy/.goreleaser.yaml
@@ -348,3 +350,40 @@ jobs:
uses: rajatjindal/krew-release-bot@v0.0.46
with:
krew_template_file: deploy/krew/support-bundle.yaml
# summary jobs, these jobs will only run if all the other jobs have succeeded
validate-pr-tests:
runs-on: ubuntu-latest
needs:
- test
- test-integration
- run-examples
- compile-collect
- validate-preflight
- validate-preflight-e2e
- validate-supportbundle
- validate-supportbundle-e2e
- validate-supportbundle-e2e-go-test
- ensure-schemas-are-generated
steps:
- run: echo "All PR tests passed"
# this job will validate that the validation did not fail and that all pr-tests succeed
# it is used for the github branch protection rule
validate-success:
runs-on: ubuntu-latest
needs:
- validate-pr-tests
if: always()
steps:
# https://docs.github.com/en/actions/learn-github-actions/contexts#needs-context
# if the validate-pr-tests job was not successful, this job will fail
- name: fail if validate-pr-tests job was not successful
if: needs.validate-pr-tests.result != 'success'
run: exit 1
# if the validate-pr-tests job was successful, this job will succeed
- name: succeed if validate-pr-tests job succeeded
if: needs.validate-pr-tests.result == 'success'
run: echo "Validation succeeded"
+1 -1
View File
@@ -22,6 +22,6 @@ jobs:
severity: 'HIGH,CRITICAL'
- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v2
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: 'trivy-results.sarif'
+4 -2
View File
@@ -16,7 +16,9 @@ jobs:
- uses: actions/checkout@v4
- name: Setup Go
uses: actions/setup-go@v4
uses: actions/setup-go@v5
with:
go-version: 1.21
- name: Install Go deps
run: go mod download
@@ -30,7 +32,7 @@ jobs:
run: trivy fs --scanners license --skip-dirs ".github" . | tee license-report.txt
- name: Upload license report artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: license-report
path: license-report.txt
+1
View File
@@ -10,3 +10,4 @@ linters:
- gocyclo
- gofmt
- gosec
- govet
+4 -4
View File
@@ -23,12 +23,12 @@ To get started we recommend:
1. Go (v1.20 or later)
2. A Kubernetes cluster (we recommend <https://k3d.io/>. This requires Docker v20.10.5 or later)
3. Fork and clone the repo to $GOPATH/src/github.com/replicatedhq/
4. Run `make support-bundle preflight` to generate binaries
5. Run `make run-troubleshoot` to generate a support bundle with the `sample-troubleshoot.yaml` in the root of the repo
3. Fork and clone repo
4. Run `make clean build` to generate binaries
5. Run `make run-support-bundle` to generate a support bundle with the `sample-troubleshoot.yaml` in the root of the repo
> Note: recent versions of Go support easy cross-compilation. For example, to cross-compile a Linux binary from MacOS:
> `GOOS=linux GOARCH=amd64 make support-bundle preflight`
> `GOOS=linux GOARCH=amd64 make clean build`
6. Install [golangci-lint] linter and run `make lint` to execute additional code linters.
+77 -45
View File
@@ -39,8 +39,8 @@ BUILDPATHS = ./pkg/... ./cmd/... ./internal/...
E2EPATHS = ./test/e2e/...
TESTFLAGS ?= -v -coverprofile cover.out
.DEFAULT: all
all: test build
.DEFAULT_GOAL := all
all: clean build test
.PHONY: ffi
ffi: fmt vet
@@ -80,30 +80,44 @@ support-bundle-e2e-go-test:
go test ${BUILDFLAGS} ${E2EPATHS} -v; \
fi
# Build all binaries in parallel ( -j )
build:
@echo "Build cli binaries"
$(MAKE) -j support-bundle preflight analyze collect
rebuild: clean build
mod-tidy:
# Build all binaries in parallel ( -j )
build: tidy
@echo "Build cli binaries"
$(MAKE) -j bin/support-bundle bin/preflight bin/analyze bin/collect
.PHONY: clean
clean:
@rm -f bin/analyze
@rm -f bin/support-bundle
@rm -f bin/collect
@rm -f bin/preflight
@rm -f bin/troubleshoot.h
@rm -f bin/troubleshoot.so
@rm -f bin/schemagen
@rm -f bin/docsgen
.PHONY: tidy
tidy:
go mod tidy
.PHONY: support-bundle
support-bundle:
bin/support-bundle:
go build ${BUILDFLAGS} ${LDFLAGS} -o bin/support-bundle github.com/replicatedhq/troubleshoot/cmd/troubleshoot
.PHONY: preflight
preflight:
bin/preflight:
go build ${BUILDFLAGS} ${LDFLAGS} -o bin/preflight github.com/replicatedhq/troubleshoot/cmd/preflight
.PHONY: analyze
analyze:
bin/analyze:
go build ${BUILDFLAGS} ${LDFLAGS} -o bin/analyze github.com/replicatedhq/troubleshoot/cmd/analyze
.PHONY: collect
collect:
bin/collect:
go build ${BUILDFLAGS} ${LDFLAGS} -o bin/collect github.com/replicatedhq/troubleshoot/cmd/collect
build-linux: tidy
@echo "Build cli binaries for Linux"
GOOS=linux GOARCH=amd64 $(MAKE) -j bin/support-bundle bin/preflight bin/analyze bin/collect
.PHONY: fmt
fmt:
go fmt ${BUILDPATHS}
@@ -138,27 +152,27 @@ check-schemas: generate schemas
fi
.PHONY: schemas
schemas: fmt vet openapischema
go build ${LDFLAGS} -o bin/schemagen github.com/replicatedhq/troubleshoot/cmd/schemagen
schemas: fmt vet openapischema bin/schemagen
./bin/schemagen --output-dir ./schemas
bin/schemagen:
go build ${LDFLAGS} -o bin/schemagen github.com/replicatedhq/troubleshoot/cmd/schemagen
.PHONY: docs
docs: fmt vet
go build ${LDFLAGS} -o bin/docsgen github.com/replicatedhq/troubleshoot/cmd/docsgen
docs: fmt vet bin/docsgen
./bin/docsgen
bin/docsgen:
go build ${LDFLAGS} -o bin/docsgen github.com/replicatedhq/troubleshoot/cmd/docsgen
controller-gen:
go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.11.2
go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.14.0
CONTROLLER_GEN=$(shell which controller-gen)
.PHONY: client-gen
client-gen:
ifeq (, $(shell which client-gen 2>/dev/null))
go install k8s.io/code-generator/cmd/client-gen@v0.28.2
CLIENT_GEN=$(shell go env GOPATH)/bin/client-gen
else
go install k8s.io/code-generator/cmd/client-gen@v0.28.8
CLIENT_GEN=$(shell which client-gen)
endif
.PHONY: release
release: export GITHUB_TOKEN = $(shell echo ${GITHUB_TOKEN_TROUBLESHOOT})
@@ -180,15 +194,15 @@ local-release:
docker push localhost:32000/preflight:alpha
.PHONY: run-preflight
run-preflight: preflight
run-preflight: bin/preflight
./bin/preflight ./examples/preflight/sample-preflight.yaml
.PHONY: run-troubleshoot
run-troubleshoot: support-bundle
.PHONY: run-support-bundle
run-support-bundle: bin/support-bundle
./bin/support-bundle ./examples/support-bundle/sample-supportbundle.yaml
.PHONY: run-analyze
run-analyze: analyze
run-analyze: bin/analyze
./bin/analyze --analyzers ./examples/support-bundle/sample-analyzers.yaml ./support-bundle.tar.gz
.PHONY: init-sbom
@@ -212,20 +226,6 @@ sbom: sbom/assets/troubleshoot-sbom.tgz
cosign sign-blob -key cosign.key sbom/assets/troubleshoot-sbom.tgz > sbom/assets/troubleshoot-sbom.tgz.sig
cosign public-key -key cosign.key -outfile sbom/assets/key.pub
longhorn:
git clone https://github.com/longhorn/longhorn-manager.git
cd longhorn-manager && git checkout v1.2.2 && cd ..
rm -rf pkg/longhorn
mv longhorn-manager/k8s/pkg pkg/longhorn
mv longhorn-manager/types pkg/longhorn/types
mv longhorn-manager/util pkg/longhorn/util
rm -rf pkg/longhorn/util/daemon
rm -rf pkg/longhorn/util/server
find pkg/longhorn -type f | xargs sed -i "s/github.com\/longhorn\/longhorn-manager\/k8s\/pkg/github.com\/replicatedhq\/troubleshoot\/pkg\/longhorn/g"
find pkg/longhorn -type f | xargs sed -i "s/github.com\/longhorn\/longhorn-manager\/types/github.com\/replicatedhq\/troubleshoot\/pkg\/longhorn\/types/g"
find pkg/longhorn -type f | xargs sed -i "s/github.com\/longhorn\/longhorn-manager\/util/github.com\/replicatedhq\/troubleshoot\/pkg\/longhorn\/util/g"
rm -rf longhorn-manager
.PHONY: scan
scan:
trivy fs \
@@ -236,11 +236,11 @@ scan:
./
.PHONY: lint
lint: fmt vet
lint:
golangci-lint run --new -c .golangci.yaml ${BUILDPATHS}
.PHONY: lint-and-fix
lint-and-fix: fmt vet
lint-and-fix:
golangci-lint run --new --fix -c .golangci.yaml ${BUILDPATHS}
.PHONY: watch
@@ -256,3 +256,35 @@ watchrsync: npm-install
npm-install:
npm --version 2>&1 >/dev/null || ( echo "npm not installed; install npm to set up watchrsync" && exit 1 )
npm list gaze-run-interrupt || npm install install --no-save gaze-run-interrupt@~2.0.0
######## Lagacy make targets ###########
# Deprecated: These can be removed
.PHONY: support-bundle
support-bundle: clean bin/support-bundle
.PHONY: preflight
preflight: clean bin/preflight
.PHONY: analyze
analyze: clean bin/analyze
.PHONY: collect
collect: clean bin/collect
.PHONY: run-troubleshoot
run-troubleshoot: run-support-bundle
longhorn:
git clone https://github.com/longhorn/longhorn-manager.git
cd longhorn-manager && git checkout v1.2.2 && cd ..
rm -rf pkg/longhorn
mv longhorn-manager/k8s/pkg pkg/longhorn
mv longhorn-manager/types pkg/longhorn/types
mv longhorn-manager/util pkg/longhorn/util
rm -rf pkg/longhorn/util/daemon
rm -rf pkg/longhorn/util/server
find pkg/longhorn -type f | xargs sed -i "s/github.com\/longhorn\/longhorn-manager\/k8s\/pkg/github.com\/replicatedhq\/troubleshoot\/pkg\/longhorn/g"
find pkg/longhorn -type f | xargs sed -i "s/github.com\/longhorn\/longhorn-manager\/types/github.com\/replicatedhq\/troubleshoot\/pkg\/longhorn\/types/g"
find pkg/longhorn -type f | xargs sed -i "s/github.com\/longhorn\/longhorn-manager\/util/github.com\/replicatedhq\/troubleshoot\/pkg\/longhorn\/util/g"
rm -rf longhorn-manager
+1 -1
View File
@@ -27,7 +27,7 @@ func runAnalyzers(v *viper.Viper, bundlePath string) error {
} else {
if !util.IsURL(specPath) {
// TODO: Better error message when we do not have a file/url etc
return fmt.Errorf("%s is not a URL and was not found (err %s)", specPath, err)
return fmt.Errorf("%s is not a URL and was not found", specPath)
}
req, err := http.NewRequest("GET", specPath, nil)
+1 -1
View File
@@ -58,7 +58,7 @@ func runCollect(v *viper.Viper, arg string) error {
collectorContent = b
} else {
if !util.IsURL(arg) {
return fmt.Errorf("%s is not a URL and was not found (err %s)", arg, err)
return fmt.Errorf("%s is not a URL and was not found", arg)
}
req, err := http.NewRequest("GET", arg, nil)
+1
View File
@@ -71,6 +71,7 @@ that a cluster meets the requirements to run an application.`,
// Dry run flag should be in cmd.PersistentFlags() flags made available to all subcommands
// Adding here to avoid that
cmd.Flags().Bool("dry-run", false, "print the preflight spec without running preflight checks")
cmd.Flags().Bool("no-uri", false, "When this flag is used, Preflight does not attempt to retrieve the spec referenced by the uri: field`")
k8sutil.AddFlags(cmd.Flags())
+1 -1
View File
@@ -91,7 +91,7 @@ func downloadAnalyzerSpec(specPath string) (string, error) {
specContent = string(b)
} else {
if !util.IsURL(specPath) {
return "", fmt.Errorf("%s is not a URL and was not found (err %s)", specPath, err)
return "", fmt.Errorf("%s is not a URL and was not found", specPath)
}
req, err := http.NewRequest("GET", specPath, nil)
+78 -37
View File
@@ -106,6 +106,22 @@ func runTroubleshoot(v *viper.Viper, args []string) error {
})
}
if interactive {
c := color.New()
c.Println(fmt.Sprintf("\r%s\r", cursor.ClearEntireLine()))
}
if interactive {
if len(mainBundle.Spec.HostCollectors) > 0 && !util.IsRunningAsRoot() {
fmt.Print(cursor.Show())
if util.PromptYesNo(util.HOST_COLLECTORS_RUN_AS_ROOT_PROMPT) {
fmt.Println("Exiting...")
return nil
}
fmt.Print(cursor.Hide())
}
}
var wg sync.WaitGroup
collectorCB := func(c chan interface{}, msg string) { c <- msg }
progressChan := make(chan interface{})
@@ -174,11 +190,6 @@ func runTroubleshoot(v *viper.Viper, args []string) error {
nonInteractiveOutput := analysisOutput{}
if interactive {
c := color.New()
c.Println(fmt.Sprintf("\r%s\r", cursor.ClearEntireLine()))
}
response, err := supportbundle.CollectSupportBundleFromSpec(&mainBundle.Spec, additionalRedactors, createOpts)
if err != nil {
return errors.Wrap(err, "failed to run collect and analyze process")
@@ -232,24 +243,45 @@ the %s Admin Console to begin analysis.`
return nil
}
func loadSupportBundleSpecsFromURIs(ctx context.Context, kinds *loader.TroubleshootKinds) (*loader.TroubleshootKinds, error) {
remoteRawSpecs := []string{}
// loadSupportBundleSpecsFromURIs loads support bundle specs from URIs
func loadSupportBundleSpecsFromURIs(ctx context.Context, kinds *loader.TroubleshootKinds) error {
moreKinds := loader.NewTroubleshootKinds()
// iterate through original kinds and replace any support bundle spec with provided uri spec
for _, s := range kinds.SupportBundlesV1Beta2 {
if s.Spec.Uri != "" && util.IsURL(s.Spec.Uri) {
// We are using LoadSupportBundleSpec function here since it handles prompting
// users to accept insecure connections
// There is an opportunity to refactor this code in favour of the Loader APIs
rawSpec, err := supportbundle.LoadSupportBundleSpec(s.Spec.Uri)
if err != nil {
return nil, errors.Wrapf(err, "failed to load support bundle from URI %q", s.Spec.Uri)
}
remoteRawSpecs = append(remoteRawSpecs, string(rawSpec))
if s.Spec.Uri == "" || !util.IsURL(s.Spec.Uri) {
moreKinds.SupportBundlesV1Beta2 = append(moreKinds.SupportBundlesV1Beta2, s)
continue
}
// We are using LoadSupportBundleSpec function here since it handles prompting
// users to accept insecure connections
// There is an opportunity to refactor this code in favour of the Loader APIs
// TODO: Pass ctx to LoadSupportBundleSpec
rawSpec, err := supportbundle.LoadSupportBundleSpec(s.Spec.Uri)
if err != nil {
// add back original spec
moreKinds.SupportBundlesV1Beta2 = append(moreKinds.SupportBundlesV1Beta2, s)
// In the event a spec can't be loaded, we'll just skip it and print a warning
klog.Warningf("unable to load support bundle from URI: %q: %v", s.Spec.Uri, err)
continue
}
k, err := loader.LoadSpecs(ctx, loader.LoadOptions{RawSpec: string(rawSpec)})
if err != nil {
// add back original spec
moreKinds.SupportBundlesV1Beta2 = append(moreKinds.SupportBundlesV1Beta2, s)
klog.Warningf("unable to load spec: %v", err)
continue
}
// finally append the uri spec
moreKinds.SupportBundlesV1Beta2 = append(moreKinds.SupportBundlesV1Beta2, k.SupportBundlesV1Beta2...)
}
return loader.LoadSpecs(ctx, loader.LoadOptions{
RawSpecs: remoteRawSpecs,
})
kinds.SupportBundlesV1Beta2 = moreKinds.SupportBundlesV1Beta2
return nil
}
func loadSpecs(ctx context.Context, args []string, client kubernetes.Interface) (*troubleshootv1beta2.SupportBundle, *troubleshootv1beta2.Redactor, error) {
@@ -261,12 +293,12 @@ func loadSpecs(ctx context.Context, args []string, client kubernetes.Interface)
}
// Load additional specs from support bundle URIs
// only when no-uri flag is not set and no URLs are provided in the args
if !viper.GetBool("no-uri") {
moreKinds, err := loadSupportBundleSpecsFromURIs(ctx, kinds)
err := loadSupportBundleSpecsFromURIs(ctx, kinds)
if err != nil {
return nil, nil, err
klog.Warningf("unable to load support bundles from URIs: %v", err)
}
kinds.Add(moreKinds)
}
// Check if we have any collectors to run in the troubleshoot specs
@@ -295,25 +327,28 @@ func loadSpecs(ctx context.Context, args []string, client kubernetes.Interface)
}
for _, c := range kinds.CollectorsV1Beta2 {
mainBundle.Spec.Collectors = append(mainBundle.Spec.Collectors, c.Spec.Collectors...)
mainBundle.Spec.Collectors = util.Append(mainBundle.Spec.Collectors, c.Spec.Collectors)
}
for _, hc := range kinds.HostCollectorsV1Beta2 {
mainBundle.Spec.HostCollectors = append(mainBundle.Spec.HostCollectors, hc.Spec.Collectors...)
mainBundle.Spec.HostCollectors = util.Append(mainBundle.Spec.HostCollectors, hc.Spec.Collectors)
}
// Ensure cluster info and cluster resources collectors are in the merged spec
// We need to add them here so when we --dry-run, these collectors are included.
// supportbundle.runCollectors duplicates this bit. We'll need to refactor it out later
// when its clearer what other code depends on this logic e.g KOTS
mainBundle.Spec.Collectors = collect.EnsureCollectorInList(
mainBundle.Spec.Collectors,
troubleshootv1beta2.Collect{ClusterInfo: &troubleshootv1beta2.ClusterInfo{}},
)
mainBundle.Spec.Collectors = collect.EnsureCollectorInList(
mainBundle.Spec.Collectors,
troubleshootv1beta2.Collect{ClusterResources: &troubleshootv1beta2.ClusterResources{}},
)
if !(len(mainBundle.Spec.HostCollectors) > 0 && len(mainBundle.Spec.Collectors) == 0) {
// Always add default collectors unless we only have host collectors
// We need to add them here so when we --dry-run, these collectors
// are included. supportbundle.runCollectors duplicates this bit.
// We'll need to refactor it out later when its clearer what other
// code depends on this logic e.g KOTS
mainBundle.Spec.Collectors = collect.EnsureCollectorInList(
mainBundle.Spec.Collectors,
troubleshootv1beta2.Collect{ClusterInfo: &troubleshootv1beta2.ClusterInfo{}},
)
mainBundle.Spec.Collectors = collect.EnsureCollectorInList(
mainBundle.Spec.Collectors,
troubleshootv1beta2.Collect{ClusterResources: &troubleshootv1beta2.ClusterResources{}},
)
}
additionalRedactors := &troubleshootv1beta2.Redactor{
TypeMeta: metav1.TypeMeta{
@@ -325,9 +360,15 @@ func loadSpecs(ctx context.Context, args []string, client kubernetes.Interface)
},
}
for _, r := range kinds.RedactorsV1Beta2 {
additionalRedactors.Spec.Redactors = append(additionalRedactors.Spec.Redactors, r.Spec.Redactors...)
additionalRedactors.Spec.Redactors = util.Append(additionalRedactors.Spec.Redactors, r.Spec.Redactors)
}
// dedupe specs
mainBundle.Spec.Collectors = util.Dedup(mainBundle.Spec.Collectors)
mainBundle.Spec.Analyzers = util.Dedup(mainBundle.Spec.Analyzers)
mainBundle.Spec.HostCollectors = util.Dedup(mainBundle.Spec.HostCollectors)
mainBundle.Spec.HostAnalyzers = util.Dedup(mainBundle.Spec.HostAnalyzers)
return mainBundle, additionalRedactors, nil
}
+383 -15
View File
@@ -2,15 +2,37 @@ package cli
import (
"context"
"encoding/json"
"net/http"
"net/http/httptest"
"strings"
"testing"
"time"
"github.com/replicatedhq/troubleshoot/internal/testutils"
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
"github.com/replicatedhq/troubleshoot/pkg/httputil"
"github.com/replicatedhq/troubleshoot/pkg/loader"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
testclient "k8s.io/client-go/kubernetes/fake"
)
func templSpec() string {
return `
apiVersion: troubleshoot.sh/v1beta2
kind: SupportBundle
metadata:
name: sb-1
spec:
uri: $MY_URI
collectors:
- configMap:
name: kube-root-ca.crt
namespace: default
`
}
func Test_loadSupportBundleSpecsFromURIs(t *testing.T) {
// Run a webserver to serve the spec
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
@@ -25,27 +47,373 @@ spec:
}))
defer srv.Close()
orig := `
apiVersion: troubleshoot.sh/v1beta2
kind: SupportBundle
metadata:
name: sb-1
spec:
uri: ` + srv.URL + `
collectors:
- configMap:
name: kube-root-ca.crt
namespace: default
`
orig := strings.ReplaceAll(templSpec(), "$MY_URI", srv.URL)
ctx := context.Background()
kinds, err := loader.LoadSpecs(ctx, loader.LoadOptions{RawSpec: orig})
require.NoError(t, err)
require.NotNil(t, kinds)
moreKinds, err := loadSupportBundleSpecsFromURIs(ctx, kinds)
assert.Len(t, kinds.SupportBundlesV1Beta2, 1)
assert.NotNil(t, kinds.SupportBundlesV1Beta2[0].Spec.Collectors[0].ConfigMap)
err = loadSupportBundleSpecsFromURIs(ctx, kinds)
require.NoError(t, err)
require.Len(t, moreKinds.SupportBundlesV1Beta2, 1)
assert.NotNil(t, moreKinds.SupportBundlesV1Beta2[0].Spec.Collectors[0].ClusterInfo)
require.Len(t, kinds.SupportBundlesV1Beta2, 1)
assert.NotNil(t, kinds.SupportBundlesV1Beta2[0].Spec.Collectors[0].ClusterInfo)
}
func Test_loadMultipleSupportBundleSpecsWithNoURIs(t *testing.T) {
ctx := context.Background()
client := testclient.NewSimpleClientset()
specs := []string{testutils.ServeFromFilePath(t, `
apiVersion: troubleshoot.sh/v1beta2
kind: SupportBundle
metadata:
name: sb-1
spec:
collectors:
- clusterInfo:{}`), testutils.ServeFromFilePath(t, `
apiVersion: troubleshoot.sh/v1beta2
kind: SupportBundle
metadata:
name: sb-2
spec:
collectors:
- clusterInfo: {}`)}
sb, _, err := loadSpecs(ctx, specs, client)
require.NoError(t, err)
require.Len(t, sb.Spec.Collectors, 2)
}
func Test_loadMultipleSupportBundleSpecsWithURIs(t *testing.T) {
ctx := context.Background()
client := testclient.NewSimpleClientset()
specFile := testutils.ServeFromFilePath(t, `
apiVersion: troubleshoot.sh/v1beta2
kind: SupportBundle
metadata:
name: sb-file
spec:
collectors:
- logs:
name: podlogs/kotsadm
selector:
- app=kotsadm
`)
// Run a webserver to serve the spec
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(`
apiVersion: troubleshoot.sh/v1beta2
kind: SupportBundle
metadata:
name: sb-uri
spec:
collectors:
- clusterInfo: {}`))
}))
defer srv.Close()
orig := strings.ReplaceAll(templSpec(), "$MY_URI", srv.URL)
specUri := testutils.ServeFromFilePath(t, orig)
specs := []string{specFile, specUri}
sb, _, err := loadSpecs(ctx, specs, client)
require.NoError(t, err)
assert.NotNil(t, sb.Spec.Collectors[0].Logs)
assert.Nil(t, sb.Spec.Collectors[1].ConfigMap) // original spec gone
assert.NotNil(t, sb.Spec.Collectors[1].ClusterInfo) // new spec from URI
}
func Test_loadSupportBundleSpecsFromURIs_TimeoutError(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
time.Sleep(2 * time.Second) // this will cause a timeout
}))
defer srv.Close()
ctx := context.Background()
kinds, err := loader.LoadSpecs(ctx, loader.LoadOptions{
RawSpec: strings.ReplaceAll(templSpec(), "$MY_URI", srv.URL),
})
require.NoError(t, err)
// Set the timeout on the http client to 10ms
// supportbundle.LoadSupportBundleSpec does not yet use the context
before := httputil.GetHttpClient().Timeout
httputil.GetHttpClient().Timeout = 10 * time.Millisecond
defer func() {
// Reinstate the original timeout. Its a global var so we need to reset it
httputil.GetHttpClient().Timeout = before
}()
beforeJSON, err := json.Marshal(kinds)
require.NoError(t, err)
err = loadSupportBundleSpecsFromURIs(ctx, kinds)
require.NoError(t, err)
afterJSON, err := json.Marshal(kinds)
require.NoError(t, err)
assert.JSONEq(t, string(beforeJSON), string(afterJSON))
}
func Test_loadSupportBundleSpecs(t *testing.T) {
tests := []struct {
name string
args []string
expected troubleshootv1beta2.SupportBundleSpec
}{
{
name: "empty collectors array in spec, default collectors added",
args: []string{testutils.ServeFromFilePath(t, `
apiVersion: troubleshoot.sh/v1beta2
kind: SupportBundle
spec:
collectors: []
`)},
expected: troubleshootv1beta2.SupportBundleSpec{
Collectors: []*troubleshootv1beta2.Collect{
{
ClusterInfo: &troubleshootv1beta2.ClusterInfo{},
},
{
ClusterResources: &troubleshootv1beta2.ClusterResources{},
},
},
},
},
{
name: "no collectors defined in spec, default collectors added",
args: []string{testutils.ServeFromFilePath(t, `
apiVersion: troubleshoot.sh/v1beta2
kind: SupportBundle
spec:
analyzers: []
`)},
expected: troubleshootv1beta2.SupportBundleSpec{
Collectors: []*troubleshootv1beta2.Collect{
{
ClusterInfo: &troubleshootv1beta2.ClusterInfo{},
},
{
ClusterResources: &troubleshootv1beta2.ClusterResources{},
},
},
Analyzers: []*troubleshootv1beta2.Analyze{},
},
},
{
name: "collectors present but defaults missing, default collectors added",
args: []string{testutils.ServeFromFilePath(t, `
apiVersion: troubleshoot.sh/v1beta2
kind: SupportBundle
spec:
collectors:
- logs: {}
`)},
expected: troubleshootv1beta2.SupportBundleSpec{
Collectors: []*troubleshootv1beta2.Collect{
{
Logs: &troubleshootv1beta2.Logs{},
},
{
ClusterInfo: &troubleshootv1beta2.ClusterInfo{},
},
{
ClusterResources: &troubleshootv1beta2.ClusterResources{},
},
},
},
},
{
name: "empty support bundle spec adds default collectors",
args: []string{testutils.ServeFromFilePath(t, `
apiVersion: troubleshoot.sh/v1beta2
kind: SupportBundle
`)},
expected: troubleshootv1beta2.SupportBundleSpec{
Collectors: []*troubleshootv1beta2.Collect{
{
ClusterInfo: &troubleshootv1beta2.ClusterInfo{},
},
{
ClusterResources: &troubleshootv1beta2.ClusterResources{},
},
},
},
},
{
name: "sb spec with host collectors does not add default collectors",
args: []string{testutils.ServeFromFilePath(t, `
apiVersion: troubleshoot.sh/v1beta2
kind: SupportBundle
spec:
hostCollectors:
- cpu: {}
`)},
expected: troubleshootv1beta2.SupportBundleSpec{
HostCollectors: []*troubleshootv1beta2.HostCollect{
{
CPU: &troubleshootv1beta2.CPU{},
},
},
},
},
{
name: "host collector spec with collectors does not add default collectors",
args: []string{testutils.ServeFromFilePath(t, `
apiVersion: troubleshoot.sh/v1beta2
kind: HostCollector
spec:
collectors:
- cpu: {}
`)},
expected: troubleshootv1beta2.SupportBundleSpec{
HostCollectors: []*troubleshootv1beta2.HostCollect{
{
CPU: &troubleshootv1beta2.CPU{},
},
},
},
},
{
name: "sb spec with host and in-cluster collectors adds default collectors",
args: []string{testutils.ServeFromFilePath(t, `
apiVersion: troubleshoot.sh/v1beta2
kind: SupportBundle
spec:
hostCollectors:
- cpu: {}
collectors:
- logs: {}
`)},
expected: troubleshootv1beta2.SupportBundleSpec{
HostCollectors: []*troubleshootv1beta2.HostCollect{
{
CPU: &troubleshootv1beta2.CPU{},
},
},
Collectors: []*troubleshootv1beta2.Collect{
{
Logs: &troubleshootv1beta2.Logs{},
},
{
ClusterInfo: &troubleshootv1beta2.ClusterInfo{},
},
{
ClusterResources: &troubleshootv1beta2.ClusterResources{},
},
},
},
},
{
name: "sb spec with host collectors and empty in-cluster collectors does not default collectors",
args: []string{testutils.ServeFromFilePath(t, `
apiVersion: troubleshoot.sh/v1beta2
kind: SupportBundle
spec:
hostCollectors:
- cpu: {}
collectors: []
`)},
expected: troubleshootv1beta2.SupportBundleSpec{
HostCollectors: []*troubleshootv1beta2.HostCollect{
{
CPU: &troubleshootv1beta2.CPU{},
},
},
Collectors: []*troubleshootv1beta2.Collect{},
},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
ctx := context.Background()
client := testclient.NewSimpleClientset()
sb, _, err := loadSpecs(ctx, test.args, client)
require.NoError(t, err)
assert.Equal(t, test.expected, sb.Spec)
})
}
}
func Test_loadDuplicatedBundleSpecs(t *testing.T) {
spec := testutils.ServeFromFilePath(t, `
apiVersion: troubleshoot.sh/v1beta2
kind: SupportBundle
metadata:
name: sb
spec:
collectors:
- helm: {}
analyzers:
- clusterVersion: {}
hostCollectors:
- cpu: {}
hostAnalyzers:
- cpu: {}
`)
args := []string{spec, spec}
ctx := context.Background()
client := testclient.NewSimpleClientset()
sb, _, err := loadSpecs(ctx, args, client)
require.NoError(t, err)
assert.Len(t, sb.Spec.Collectors, 1+2) // default clusterInfo + clusterResources
assert.Len(t, sb.Spec.Analyzers, 1)
assert.Len(t, sb.Spec.HostCollectors, 1)
assert.Len(t, sb.Spec.HostAnalyzers, 1)
}
func Test_loadSpecsFromURL(t *testing.T) {
// Run a webserver to serve the URI spec
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(`
apiVersion: troubleshoot.sh/v1beta2
kind: SupportBundle
metadata:
name: sb-2
spec:
collectors:
- logs:
name: podlogs/kotsadm
selector:
- app=kotsadm`))
}))
defer srv.Close()
// update URI spec with the server URL
orig := strings.ReplaceAll(templSpec(), "$MY_URI", srv.URL)
// now create a webserver to serve the spec with URI
srv = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(orig))
}))
defer srv.Close()
fileSpec := testutils.ServeFromFilePath(t, `
apiVersion: troubleshoot.sh/v1beta2
kind: SupportBundle
metadata:
name: sb
spec:
collectors:
- helm: {}`)
// test and ensure that URI spec is not loaded
ctx := context.Background()
client := testclient.NewSimpleClientset()
sb, _, err := loadSpecs(ctx, []string{fileSpec, srv.URL}, client)
require.NoError(t, err)
assert.Len(t, sb.Spec.Collectors, 2+2) // default + clusterInfo + clusterResources
assert.NotNil(t, sb.Spec.Collectors[0].Helm) // come from the file spec
assert.NotNil(t, sb.Spec.Collectors[1].ConfigMap) // come from the original spec
assert.Nil(t, sb.Spec.Collectors[1].Logs) // come from the URI spec
}
@@ -3,8 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.11.2
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.14.0
name: analyzers.troubleshoot.replicated.com
spec:
group: troubleshoot.replicated.com
@@ -21,14 +20,19 @@ spec:
description: Analyzer is the Schema for the analyzers API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
@@ -3,8 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.11.2
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.14.0
name: collectors.troubleshoot.replicated.com
spec:
group: troubleshoot.replicated.com
@@ -21,14 +20,19 @@ spec:
description: Collector is the Schema for the collectors API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
@@ -164,10 +168,10 @@ spec:
insecureSkipVerify:
type: boolean
timeout:
description: A Duration represents the elapsed time
between two instants as an int64 nanosecond count.
The representation limits the largest representable
duration to approximately 290 years.
description: |-
A Duration represents the elapsed time between two instants
as an int64 nanosecond count. The representation limits the
largest representable duration to approximately 290 years.
format: int64
type: integer
url:
@@ -188,10 +192,10 @@ spec:
insecureSkipVerify:
type: boolean
timeout:
description: A Duration represents the elapsed time
between two instants as an int64 nanosecond count.
The representation limits the largest representable
duration to approximately 290 years.
description: |-
A Duration represents the elapsed time between two instants
as an int64 nanosecond count. The representation limits the
largest representable duration to approximately 290 years.
format: int64
type: integer
url:
@@ -210,10 +214,10 @@ spec:
insecureSkipVerify:
type: boolean
timeout:
description: A Duration represents the elapsed time
between two instants as an int64 nanosecond count.
The representation limits the largest representable
duration to approximately 290 years.
description: |-
A Duration represents the elapsed time between two instants
as an int64 nanosecond count. The representation limits the
largest representable duration to approximately 290 years.
format: int64
type: integer
url:
@@ -3,8 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.11.2
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.14.0
name: preflights.troubleshoot.replicated.com
spec:
group: troubleshoot.replicated.com
@@ -21,14 +20,19 @@ spec:
description: Preflight is the Schema for the preflights API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
@@ -836,10 +840,10 @@ spec:
insecureSkipVerify:
type: boolean
timeout:
description: A Duration represents the elapsed time
between two instants as an int64 nanosecond count.
The representation limits the largest representable
duration to approximately 290 years.
description: |-
A Duration represents the elapsed time between two instants
as an int64 nanosecond count. The representation limits the
largest representable duration to approximately 290 years.
format: int64
type: integer
url:
@@ -860,10 +864,10 @@ spec:
insecureSkipVerify:
type: boolean
timeout:
description: A Duration represents the elapsed time
between two instants as an int64 nanosecond count.
The representation limits the largest representable
duration to approximately 290 years.
description: |-
A Duration represents the elapsed time between two instants
as an int64 nanosecond count. The representation limits the
largest representable duration to approximately 290 years.
format: int64
type: integer
url:
@@ -882,10 +886,10 @@ spec:
insecureSkipVerify:
type: boolean
timeout:
description: A Duration represents the elapsed time
between two instants as an int64 nanosecond count.
The representation limits the largest representable
duration to approximately 290 years.
description: |-
A Duration represents the elapsed time between two instants
as an int64 nanosecond count. The representation limits the
largest representable duration to approximately 290 years.
format: int64
type: integer
url:
@@ -3,8 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.11.2
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.14.0
name: redactors.troubleshoot.replicated.com
spec:
group: troubleshoot.replicated.com
@@ -21,14 +20,19 @@ spec:
description: Redactor is the Schema for the redaction API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
@@ -3,8 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.11.2
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.14.0
name: supportbundles.troubleshoot.replicated.com
spec:
group: troubleshoot.replicated.com
@@ -21,14 +20,19 @@ spec:
description: SupportBundle is the Schema for the SupportBundles API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
@@ -867,10 +871,10 @@ spec:
insecureSkipVerify:
type: boolean
timeout:
description: A Duration represents the elapsed time
between two instants as an int64 nanosecond count.
The representation limits the largest representable
duration to approximately 290 years.
description: |-
A Duration represents the elapsed time between two instants
as an int64 nanosecond count. The representation limits the
largest representable duration to approximately 290 years.
format: int64
type: integer
url:
@@ -891,10 +895,10 @@ spec:
insecureSkipVerify:
type: boolean
timeout:
description: A Duration represents the elapsed time
between two instants as an int64 nanosecond count.
The representation limits the largest representable
duration to approximately 290 years.
description: |-
A Duration represents the elapsed time between two instants
as an int64 nanosecond count. The representation limits the
largest representable duration to approximately 290 years.
format: int64
type: integer
url:
@@ -913,10 +917,10 @@ spec:
insecureSkipVerify:
type: boolean
timeout:
description: A Duration represents the elapsed time
between two instants as an int64 nanosecond count.
The representation limits the largest representable
duration to approximately 290 years.
description: |-
A Duration represents the elapsed time between two instants
as an int64 nanosecond count. The representation limits the
largest representable duration to approximately 290 years.
format: int64
type: integer
url:
+357 -8
View File
@@ -3,8 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.11.2
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.14.0
name: analyzers.troubleshoot.sh
spec:
group: troubleshoot.sh
@@ -21,14 +20,19 @@ spec:
description: Analyzer is the Schema for the analyzers API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
@@ -559,6 +563,165 @@ spec:
required:
- outcomes
type: object
event:
properties:
annotations:
additionalProperties:
type: string
type: object
checkName:
type: string
collectorName:
type: string
exclude:
type: BoolString
kind:
type: string
namespace:
type: string
outcomes:
items:
properties:
fail:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
pass:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
warn:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
type: object
type: array
reason:
type: string
regex:
type: string
strict:
type: BoolString
required:
- collectorName
- outcomes
- reason
type: object
goldpinger:
properties:
annotations:
additionalProperties:
type: string
type: object
checkName:
type: string
collectorName:
type: string
exclude:
type: BoolString
filePath:
type: string
outcomes:
items:
properties:
fail:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
pass:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
warn:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
type: object
type: array
strict:
type: BoolString
required:
- collectorName
type: object
http:
properties:
annotations:
additionalProperties:
type: string
type: object
checkName:
type: string
collectorName:
type: string
exclude:
type: BoolString
outcomes:
items:
properties:
fail:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
pass:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
warn:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
type: object
type: array
strict:
type: BoolString
required:
- outcomes
type: object
imagePullSecret:
properties:
annotations:
@@ -931,6 +1094,66 @@ spec:
- collectorName
- outcomes
type: object
nodeMetrics:
properties:
annotations:
additionalProperties:
type: string
type: object
checkName:
type: string
collectorName:
type: string
exclude:
type: BoolString
filters:
properties:
pvc:
properties:
nameRegex:
type: string
namespace:
type: string
type: object
type: object
outcomes:
items:
properties:
fail:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
pass:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
warn:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
type: object
type: array
strict:
type: BoolString
required:
- collectorName
- outcomes
type: object
nodeResources:
properties:
annotations:
@@ -1489,6 +1712,19 @@ spec:
required:
- outcomes
type: object
velero:
properties:
annotations:
additionalProperties:
type: string
type: object
checkName:
type: string
exclude:
type: BoolString
strict:
type: BoolString
type: object
weaveReport:
properties:
annotations:
@@ -2112,6 +2348,117 @@ spec:
required:
- outcomes
type: object
jsonCompare:
properties:
annotations:
additionalProperties:
type: string
type: object
checkName:
type: string
collectorName:
type: string
exclude:
type: BoolString
fileName:
type: string
jsonPath:
type: string
outcomes:
items:
properties:
fail:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
pass:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
warn:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
type: object
type: array
path:
type: string
strict:
type: BoolString
value:
type: string
required:
- outcomes
type: object
kernelConfigs:
properties:
annotations:
additionalProperties:
type: string
type: object
checkName:
type: string
collectorName:
type: string
exclude:
type: BoolString
outcomes:
items:
properties:
fail:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
pass:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
warn:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
type: object
type: array
selectedConfigs:
items:
type: string
type: array
strict:
type: BoolString
required:
- outcomes
- selectedConfigs
type: object
kernelModules:
properties:
annotations:
@@ -2616,6 +2963,8 @@ spec:
type: object
type: object
type: array
uri:
type: string
type: object
status:
description: AnalyzerStatus defines the observed state of Analyzer
File diff suppressed because it is too large Load Diff
+223 -46
View File
@@ -3,8 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.11.2
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.14.0
name: hostcollectors.troubleshoot.sh
spec:
group: troubleshoot.sh
@@ -21,14 +20,19 @@ spec:
description: HostCollector is the Schema for the collectors API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
@@ -584,6 +588,117 @@ spec:
required:
- outcomes
type: object
jsonCompare:
properties:
annotations:
additionalProperties:
type: string
type: object
checkName:
type: string
collectorName:
type: string
exclude:
type: BoolString
fileName:
type: string
jsonPath:
type: string
outcomes:
items:
properties:
fail:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
pass:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
warn:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
type: object
type: array
path:
type: string
strict:
type: BoolString
value:
type: string
required:
- outcomes
type: object
kernelConfigs:
properties:
annotations:
additionalProperties:
type: string
type: object
checkName:
type: string
collectorName:
type: string
exclude:
type: BoolString
outcomes:
items:
properties:
fail:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
pass:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
warn:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
type: object
type: array
selectedConfigs:
items:
type: string
type: array
strict:
type: BoolString
required:
- outcomes
- selectedConfigs
type: object
kernelModules:
properties:
annotations:
@@ -1125,6 +1240,15 @@ spec:
required:
- paths
type: object
cgroups:
properties:
collectorName:
type: string
exclude:
type: BoolString
mountPoint:
type: string
type: object
copy:
properties:
collectorName:
@@ -1155,9 +1279,9 @@ spec:
- path
type: object
filesystemPerformance:
description: FilesystemPerformance benchmarks sequential write
latency on a single file. The optional background IOPS feature
attempts to mimic real-world conditions by running read and
description: |-
FilesystemPerformance benchmarks sequential write latency on a single file.
The optional background IOPS feature attempts to mimic real-world conditions by running read and
write workloads prior to and during benchmark execution.
properties:
backgroundIOPSWarmupSeconds:
@@ -1165,34 +1289,33 @@ spec:
write workloads prior to starting the benchmarks.
type: integer
backgroundReadIOPS:
description: The target read IOPS to run while benchmarking.
This is a limit and there is no guarantee it will be reached.
This is the total IOPS for all background read jobs.
description: |-
The target read IOPS to run while benchmarking. This is a limit and there is no guarantee
it will be reached. This is the total IOPS for all background read jobs.
type: integer
backgroundReadIOPSJobs:
description: Number of threads to use for background read
IOPS. This should be set high enough to reach the target
specified in BackgrounReadIOPS.
description: |-
Number of threads to use for background read IOPS. This should be set high enough to reach
the target specified in BackgrounReadIOPS.
type: integer
backgroundWriteIOPS:
description: The target write IOPS to run while benchmarking.
This is a limit and there is no guarantee it will be reached.
This is the total IOPS for all background write jobs.
description: |-
The target write IOPS to run while benchmarking. This is a limit and there is no guarantee
it will be reached. This is the total IOPS for all background write jobs.
type: integer
backgroundWriteIOPSJobs:
description: 'Number of threads to use for background write
IOPS. This should be set high enough to reach the target
specified in BackgroundWriteIOPS. Example: If BackgroundWriteIOPS
is 100 and write latency is 10ms then a single job would
barely be able to reach 100 IOPS so this should be at
least 2.'
description: |-
Number of threads to use for background write IOPS. This should be set high enough to reach
the target specified in BackgroundWriteIOPS.
Example: If BackgroundWriteIOPS is 100 and write latency is 10ms then a single job would
barely be able to reach 100 IOPS so this should be at least 2.
type: integer
collectorName:
type: string
datasync:
description: Whether to call datasync on the file after
each write. Skipped if Sync is also true. Does not apply
to background IOPS task.
description: |-
Whether to call datasync on the file after each write. Skipped if Sync is also true. Does not
apply to background IOPS task.
type: boolean
directory:
description: The directory where the benchmark will create
@@ -1204,16 +1327,14 @@ spec:
exclude:
type: BoolString
fileSize:
description: The size of the file used in the benchmark.
The number of IO operations for the benchmark will be
FileSize / OperationSizeBytes. Accepts valid Kubernetes
resource units such as Mi.
description: |-
The size of the file used in the benchmark. The number of IO operations for the benchmark
will be FileSize / OperationSizeBytes. Accepts valid Kubernetes resource units such as Mi.
type: string
operationSize:
description: The size of each write operation performed
while benchmarking. This does not apply to the background
IOPS feature if enabled, since those must be fixed at
4096.
description: |-
The size of each write operation performed while benchmarking. This does not apply to the
background IOPS feature if enabled, since those must be fixed at 4096.
format: int64
type: integer
sync:
@@ -1261,9 +1382,9 @@ spec:
insecureSkipVerify:
type: boolean
timeout:
description: Timeout is the time to wait for a server's
response. Its a duration e.g 15s, 2h30m. Missing value
or empty string or means no timeout.
description: |-
Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m.
Missing value or empty string or means no timeout.
type: string
url:
type: string
@@ -1281,9 +1402,9 @@ spec:
insecureSkipVerify:
type: boolean
timeout:
description: Timeout is the time to wait for a server's
response. Its a duration e.g 15s, 2h30m. Missing value
or empty string or means no timeout.
description: |-
Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m.
Missing value or empty string or means no timeout.
type: string
url:
type: string
@@ -1301,9 +1422,9 @@ spec:
insecureSkipVerify:
type: boolean
timeout:
description: Timeout is the time to wait for a server's
response. Its a duration e.g 15s, 2h30m. Missing value
or empty string or means no timeout.
description: |-
Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m.
Missing value or empty string or means no timeout.
type: string
url:
type: string
@@ -1337,6 +1458,42 @@ spec:
exclude:
type: BoolString
type: object
journald:
properties:
collectorName:
type: string
dmesg:
type: boolean
exclude:
type: BoolString
lines:
type: integer
output:
type: string
reverse:
type: boolean
since:
type: string
system:
type: boolean
timeout:
type: string
units:
items:
type: string
type: array
until:
type: string
utc:
type: boolean
type: object
kernelConfigs:
properties:
collectorName:
type: string
exclude:
type: BoolString
type: object
kernelModules:
properties:
collectorName:
@@ -1368,8 +1525,26 @@ spec:
type: string
command:
type: string
env:
items:
type: string
type: array
exclude:
type: BoolString
ignoreParentEnvs:
type: boolean
inheritEnvs:
items:
type: string
type: array
input:
additionalProperties:
type: string
type: object
outputDir:
type: string
timeout:
type: string
required:
- args
- command
@@ -1543,6 +1718,8 @@ spec:
type: object
type: object
type: array
uri:
type: string
type: object
status:
description: HostCollectorStatus defines the observed state of HostCollector
+259 -85
View File
@@ -3,8 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.11.2
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.14.0
name: hostpreflights.troubleshoot.sh
spec:
group: troubleshoot.sh
@@ -21,14 +20,19 @@ spec:
description: HostPreflight is the Schema for the hostpreflights API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
@@ -584,6 +588,117 @@ spec:
required:
- outcomes
type: object
jsonCompare:
properties:
annotations:
additionalProperties:
type: string
type: object
checkName:
type: string
collectorName:
type: string
exclude:
type: BoolString
fileName:
type: string
jsonPath:
type: string
outcomes:
items:
properties:
fail:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
pass:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
warn:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
type: object
type: array
path:
type: string
strict:
type: BoolString
value:
type: string
required:
- outcomes
type: object
kernelConfigs:
properties:
annotations:
additionalProperties:
type: string
type: object
checkName:
type: string
collectorName:
type: string
exclude:
type: BoolString
outcomes:
items:
properties:
fail:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
pass:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
warn:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
type: object
type: array
selectedConfigs:
items:
type: string
type: array
strict:
type: BoolString
required:
- outcomes
- selectedConfigs
type: object
kernelModules:
properties:
annotations:
@@ -1125,6 +1240,15 @@ spec:
required:
- paths
type: object
cgroups:
properties:
collectorName:
type: string
exclude:
type: BoolString
mountPoint:
type: string
type: object
copy:
properties:
collectorName:
@@ -1155,9 +1279,9 @@ spec:
- path
type: object
filesystemPerformance:
description: FilesystemPerformance benchmarks sequential write
latency on a single file. The optional background IOPS feature
attempts to mimic real-world conditions by running read and
description: |-
FilesystemPerformance benchmarks sequential write latency on a single file.
The optional background IOPS feature attempts to mimic real-world conditions by running read and
write workloads prior to and during benchmark execution.
properties:
backgroundIOPSWarmupSeconds:
@@ -1165,34 +1289,33 @@ spec:
write workloads prior to starting the benchmarks.
type: integer
backgroundReadIOPS:
description: The target read IOPS to run while benchmarking.
This is a limit and there is no guarantee it will be reached.
This is the total IOPS for all background read jobs.
description: |-
The target read IOPS to run while benchmarking. This is a limit and there is no guarantee
it will be reached. This is the total IOPS for all background read jobs.
type: integer
backgroundReadIOPSJobs:
description: Number of threads to use for background read
IOPS. This should be set high enough to reach the target
specified in BackgrounReadIOPS.
description: |-
Number of threads to use for background read IOPS. This should be set high enough to reach
the target specified in BackgrounReadIOPS.
type: integer
backgroundWriteIOPS:
description: The target write IOPS to run while benchmarking.
This is a limit and there is no guarantee it will be reached.
This is the total IOPS for all background write jobs.
description: |-
The target write IOPS to run while benchmarking. This is a limit and there is no guarantee
it will be reached. This is the total IOPS for all background write jobs.
type: integer
backgroundWriteIOPSJobs:
description: 'Number of threads to use for background write
IOPS. This should be set high enough to reach the target
specified in BackgroundWriteIOPS. Example: If BackgroundWriteIOPS
is 100 and write latency is 10ms then a single job would
barely be able to reach 100 IOPS so this should be at
least 2.'
description: |-
Number of threads to use for background write IOPS. This should be set high enough to reach
the target specified in BackgroundWriteIOPS.
Example: If BackgroundWriteIOPS is 100 and write latency is 10ms then a single job would
barely be able to reach 100 IOPS so this should be at least 2.
type: integer
collectorName:
type: string
datasync:
description: Whether to call datasync on the file after
each write. Skipped if Sync is also true. Does not apply
to background IOPS task.
description: |-
Whether to call datasync on the file after each write. Skipped if Sync is also true. Does not
apply to background IOPS task.
type: boolean
directory:
description: The directory where the benchmark will create
@@ -1204,16 +1327,14 @@ spec:
exclude:
type: BoolString
fileSize:
description: The size of the file used in the benchmark.
The number of IO operations for the benchmark will be
FileSize / OperationSizeBytes. Accepts valid Kubernetes
resource units such as Mi.
description: |-
The size of the file used in the benchmark. The number of IO operations for the benchmark
will be FileSize / OperationSizeBytes. Accepts valid Kubernetes resource units such as Mi.
type: string
operationSize:
description: The size of each write operation performed
while benchmarking. This does not apply to the background
IOPS feature if enabled, since those must be fixed at
4096.
description: |-
The size of each write operation performed while benchmarking. This does not apply to the
background IOPS feature if enabled, since those must be fixed at 4096.
format: int64
type: integer
sync:
@@ -1261,9 +1382,9 @@ spec:
insecureSkipVerify:
type: boolean
timeout:
description: Timeout is the time to wait for a server's
response. Its a duration e.g 15s, 2h30m. Missing value
or empty string or means no timeout.
description: |-
Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m.
Missing value or empty string or means no timeout.
type: string
url:
type: string
@@ -1281,9 +1402,9 @@ spec:
insecureSkipVerify:
type: boolean
timeout:
description: Timeout is the time to wait for a server's
response. Its a duration e.g 15s, 2h30m. Missing value
or empty string or means no timeout.
description: |-
Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m.
Missing value or empty string or means no timeout.
type: string
url:
type: string
@@ -1301,9 +1422,9 @@ spec:
insecureSkipVerify:
type: boolean
timeout:
description: Timeout is the time to wait for a server's
response. Its a duration e.g 15s, 2h30m. Missing value
or empty string or means no timeout.
description: |-
Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m.
Missing value or empty string or means no timeout.
type: string
url:
type: string
@@ -1337,6 +1458,42 @@ spec:
exclude:
type: BoolString
type: object
journald:
properties:
collectorName:
type: string
dmesg:
type: boolean
exclude:
type: BoolString
lines:
type: integer
output:
type: string
reverse:
type: boolean
since:
type: string
system:
type: boolean
timeout:
type: string
units:
items:
type: string
type: array
until:
type: string
utc:
type: boolean
type: object
kernelConfigs:
properties:
collectorName:
type: string
exclude:
type: BoolString
type: object
kernelModules:
properties:
collectorName:
@@ -1368,8 +1525,26 @@ spec:
type: string
command:
type: string
env:
items:
type: string
type: array
exclude:
type: BoolString
ignoreParentEnvs:
type: boolean
inheritEnvs:
items:
type: string
type: array
input:
additionalProperties:
type: string
type: object
outputDir:
type: string
timeout:
type: string
required:
- args
- command
@@ -1586,44 +1761,43 @@ spec:
- path
type: object
filesystemPerformance:
description: RemoteFilesystemPerformance benchmarks sequential
write latency on a single file. The optional background IOPS
feature attempts to mimic real-world conditions by running
read and write workloads prior to and during benchmark execution.
description: |-
RemoteFilesystemPerformance benchmarks sequential write latency on a single file.
The optional background IOPS feature attempts to mimic real-world conditions by running read and
write workloads prior to and during benchmark execution.
properties:
backgroundIOPSWarmupSeconds:
description: How long to run the background IOPS read and
write workloads prior to starting the benchmarks.
type: integer
backgroundReadIOPS:
description: The target read IOPS to run while benchmarking.
This is a limit and there is no guarantee it will be reached.
This is the total IOPS for all background read jobs.
description: |-
The target read IOPS to run while benchmarking. This is a limit and there is no guarantee
it will be reached. This is the total IOPS for all background read jobs.
type: integer
backgroundReadIOPSJobs:
description: Number of threads to use for background read
IOPS. This should be set high enough to reach the target
specified in BackgrounReadIOPS.
description: |-
Number of threads to use for background read IOPS. This should be set high enough to reach
the target specified in BackgrounReadIOPS.
type: integer
backgroundWriteIOPS:
description: The target write IOPS to run while benchmarking.
This is a limit and there is no guarantee it will be reached.
This is the total IOPS for all background write jobs.
description: |-
The target write IOPS to run while benchmarking. This is a limit and there is no guarantee
it will be reached. This is the total IOPS for all background write jobs.
type: integer
backgroundWriteIOPSJobs:
description: 'Number of threads to use for background write
IOPS. This should be set high enough to reach the target
specified in BackgroundWriteIOPS. Example: If BackgroundWriteIOPS
is 100 and write latency is 10ms then a single job would
barely be able to reach 100 IOPS so this should be at
least 2.'
description: |-
Number of threads to use for background write IOPS. This should be set high enough to reach
the target specified in BackgroundWriteIOPS.
Example: If BackgroundWriteIOPS is 100 and write latency is 10ms then a single job would
barely be able to reach 100 IOPS so this should be at least 2.
type: integer
collectorName:
type: string
datasync:
description: Whether to call datasync on the file after
each write. Skipped if Sync is also true. Does not apply
to background IOPS task.
description: |-
Whether to call datasync on the file after each write. Skipped if Sync is also true. Does not
apply to background IOPS task.
type: boolean
directory:
description: The directory where the benchmark will create
@@ -1635,16 +1809,14 @@ spec:
exclude:
type: BoolString
fileSize:
description: The size of the file used in the benchmark.
The number of IO operations for the benchmark will be
FileSize / OperationSizeBytes. Accepts valid Kubernetes
resource units such as Mi.
description: |-
The size of the file used in the benchmark. The number of IO operations for the benchmark
will be FileSize / OperationSizeBytes. Accepts valid Kubernetes resource units such as Mi.
type: string
operationSize:
description: The size of each write operation performed
while benchmarking. This does not apply to the background
IOPS feature if enabled, since those must be fixed at
4096.
description: |-
The size of each write operation performed while benchmarking. This does not apply to the
background IOPS feature if enabled, since those must be fixed at 4096.
format: int64
type: integer
sync:
@@ -1685,9 +1857,9 @@ spec:
insecureSkipVerify:
type: boolean
timeout:
description: Timeout is the time to wait for a server's
response. Its a duration e.g 15s, 2h30m. Missing value
or empty string or means no timeout.
description: |-
Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m.
Missing value or empty string or means no timeout.
type: string
url:
type: string
@@ -1705,9 +1877,9 @@ spec:
insecureSkipVerify:
type: boolean
timeout:
description: Timeout is the time to wait for a server's
response. Its a duration e.g 15s, 2h30m. Missing value
or empty string or means no timeout.
description: |-
Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m.
Missing value or empty string or means no timeout.
type: string
url:
type: string
@@ -1725,9 +1897,9 @@ spec:
insecureSkipVerify:
type: boolean
timeout:
description: Timeout is the time to wait for a server's
response. Its a duration e.g 15s, 2h30m. Missing value
or empty string or means no timeout.
description: |-
Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m.
Missing value or empty string or means no timeout.
type: string
url:
type: string
@@ -1860,6 +2032,8 @@ spec:
type: object
type: object
type: array
uri:
type: string
type: object
status:
description: HostPreflightStatus defines the observed state of HostPreflight
File diff suppressed because it is too large Load Diff
+14 -8
View File
@@ -3,8 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.11.2
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.14.0
name: redactors.troubleshoot.sh
spec:
group: troubleshoot.sh
@@ -21,14 +20,19 @@ spec:
description: Redactor is the Schema for the redaction API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
@@ -71,6 +75,8 @@ spec:
type: object
type: object
type: array
uri:
type: string
type: object
status:
description: RedactorStatus defines the observed state of Redactor
@@ -3,8 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.11.2
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.14.0
name: remotecollectors.troubleshoot.sh
spec:
group: troubleshoot.sh
@@ -21,14 +20,19 @@ spec:
description: RemoteCollector is the Schema for the remote collectors API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
@@ -109,44 +113,43 @@ spec:
- path
type: object
filesystemPerformance:
description: RemoteFilesystemPerformance benchmarks sequential
write latency on a single file. The optional background IOPS
feature attempts to mimic real-world conditions by running
read and write workloads prior to and during benchmark execution.
description: |-
RemoteFilesystemPerformance benchmarks sequential write latency on a single file.
The optional background IOPS feature attempts to mimic real-world conditions by running read and
write workloads prior to and during benchmark execution.
properties:
backgroundIOPSWarmupSeconds:
description: How long to run the background IOPS read and
write workloads prior to starting the benchmarks.
type: integer
backgroundReadIOPS:
description: The target read IOPS to run while benchmarking.
This is a limit and there is no guarantee it will be reached.
This is the total IOPS for all background read jobs.
description: |-
The target read IOPS to run while benchmarking. This is a limit and there is no guarantee
it will be reached. This is the total IOPS for all background read jobs.
type: integer
backgroundReadIOPSJobs:
description: Number of threads to use for background read
IOPS. This should be set high enough to reach the target
specified in BackgrounReadIOPS.
description: |-
Number of threads to use for background read IOPS. This should be set high enough to reach
the target specified in BackgrounReadIOPS.
type: integer
backgroundWriteIOPS:
description: The target write IOPS to run while benchmarking.
This is a limit and there is no guarantee it will be reached.
This is the total IOPS for all background write jobs.
description: |-
The target write IOPS to run while benchmarking. This is a limit and there is no guarantee
it will be reached. This is the total IOPS for all background write jobs.
type: integer
backgroundWriteIOPSJobs:
description: 'Number of threads to use for background write
IOPS. This should be set high enough to reach the target
specified in BackgroundWriteIOPS. Example: If BackgroundWriteIOPS
is 100 and write latency is 10ms then a single job would
barely be able to reach 100 IOPS so this should be at
least 2.'
description: |-
Number of threads to use for background write IOPS. This should be set high enough to reach
the target specified in BackgroundWriteIOPS.
Example: If BackgroundWriteIOPS is 100 and write latency is 10ms then a single job would
barely be able to reach 100 IOPS so this should be at least 2.
type: integer
collectorName:
type: string
datasync:
description: Whether to call datasync on the file after
each write. Skipped if Sync is also true. Does not apply
to background IOPS task.
description: |-
Whether to call datasync on the file after each write. Skipped if Sync is also true. Does not
apply to background IOPS task.
type: boolean
directory:
description: The directory where the benchmark will create
@@ -158,16 +161,14 @@ spec:
exclude:
type: BoolString
fileSize:
description: The size of the file used in the benchmark.
The number of IO operations for the benchmark will be
FileSize / OperationSizeBytes. Accepts valid Kubernetes
resource units such as Mi.
description: |-
The size of the file used in the benchmark. The number of IO operations for the benchmark
will be FileSize / OperationSizeBytes. Accepts valid Kubernetes resource units such as Mi.
type: string
operationSize:
description: The size of each write operation performed
while benchmarking. This does not apply to the background
IOPS feature if enabled, since those must be fixed at
4096.
description: |-
The size of each write operation performed while benchmarking. This does not apply to the
background IOPS feature if enabled, since those must be fixed at 4096.
format: int64
type: integer
sync:
@@ -208,9 +209,9 @@ spec:
insecureSkipVerify:
type: boolean
timeout:
description: Timeout is the time to wait for a server's
response. Its a duration e.g 15s, 2h30m. Missing value
or empty string or means no timeout.
description: |-
Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m.
Missing value or empty string or means no timeout.
type: string
url:
type: string
@@ -228,9 +229,9 @@ spec:
insecureSkipVerify:
type: boolean
timeout:
description: Timeout is the time to wait for a server's
response. Its a duration e.g 15s, 2h30m. Missing value
or empty string or means no timeout.
description: |-
Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m.
Missing value or empty string or means no timeout.
type: string
url:
type: string
@@ -248,9 +249,9 @@ spec:
insecureSkipVerify:
type: boolean
timeout:
description: Timeout is the time to wait for a server's
response. Its a duration e.g 15s, 2h30m. Missing value
or empty string or means no timeout.
description: |-
Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m.
Missing value or empty string or means no timeout.
type: string
url:
type: string
@@ -387,6 +388,8 @@ spec:
additionalProperties:
type: string
type: object
uri:
type: string
type: object
status:
description: CollectorStatus defines the observed state of Collector
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -42,7 +42,7 @@ An initially unintended benefit of using the Aggregation Layer is that any HostC
* [microk8s implementation](https://github.com/canonical/microk8s/blob/master/build-scripts/patches/0000-Kubelite-integration.patch) - bundles slightly modified binaries
* [k0s uses upstream binaries statically compiled](https://docs.k0sproject.io/v1.23.8+k0s.0/architecture/) - bundles statically compiled binaries that self extract and uses a process monitor to run them
2. Can you in fact push metadat like "Status" into an api-server or do we have to write directly to etcd?
2. Can you in fact push metadata like "Status" into an api-server or do we have to write directly to etcd?
* If we can't push to the api-server is just writing the information directly into etcd something we can do and have a reasonable expectation of compatibility?
+1 -1
View File
@@ -54,4 +54,4 @@ preflight [url] [flags]
* [preflight oci-fetch](preflight_oci-fetch.md) - Fetch a preflight from an OCI registry and print it to standard out
* [preflight version](preflight_version.md) - Print the current version and exit
###### Auto generated by spf13/cobra on 31-Aug-2023
###### Auto generated by spf13/cobra on 25-Jan-2024
+3 -2
View File
@@ -9,7 +9,8 @@ preflight oci-fetch [URI] [flags]
### Options
```
-h, --help help for oci-fetch
-h, --help help for oci-fetch
-v, --v Level number for the log level verbosity
```
### Options inherited from parent commands
@@ -33,4 +34,4 @@ preflight oci-fetch [URI] [flags]
* [preflight](preflight.md) - Run and retrieve preflight checks in a cluster
###### Auto generated by spf13/cobra on 31-Aug-2023
###### Auto generated by spf13/cobra on 25-Jan-2024
+1 -1
View File
@@ -37,4 +37,4 @@ preflight version [flags]
* [preflight](preflight.md) - Run and retrieve preflight checks in a cluster
###### Auto generated by spf13/cobra on 31-Aug-2023
###### Auto generated by spf13/cobra on 25-Jan-2024
+3 -2
View File
@@ -27,6 +27,7 @@ support-bundle [urls...] [flags]
--cpuprofile string File path to write cpu profiling data
--debug enable debug logging. This is equivalent to --v=0
--disable-compression If true, opt-out of response compression for all requests to the server
--dry-run print support bundle spec without collecting anything
-h, --help help for support-bundle
--insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--interactive enable/disable interactive mode (default true)
@@ -34,7 +35,7 @@ support-bundle [urls...] [flags]
--load-cluster-specs enable/disable loading additional troubleshoot specs found within the cluster. required when no specs are provided on the command line
--memprofile string File path to write memory profiling data
-n, --namespace string If present, the namespace scope for this CLI request
--no-uri When this flag is used, Troubleshoot does not attempt to retrieve the bundle referenced by the uri: field in the spec.`
--no-uri When this flag is used, Troubleshoot does not attempt to retrieve the spec referenced by the uri: field`
-o, --output string specify the output file path for the support bundle
--redact enable/disable default redactions (default true)
--redactors strings names of the additional redactors to use
@@ -55,4 +56,4 @@ support-bundle [urls...] [flags]
* [support-bundle redact](support-bundle_redact.md) - Redact information from a generated support bundle archive
* [support-bundle version](support-bundle_version.md) - Print the current version and exit
###### Auto generated by spf13/cobra on 31-Aug-2023
###### Auto generated by spf13/cobra on 25-Jan-2024
+1 -1
View File
@@ -30,4 +30,4 @@ support-bundle analyze [url] [flags]
* [support-bundle](support-bundle.md) - Generate a support bundle
###### Auto generated by spf13/cobra on 31-Aug-2023
###### Auto generated by spf13/cobra on 25-Jan-2024
+1 -1
View File
@@ -39,4 +39,4 @@ support-bundle redact [urls...] [flags]
* [support-bundle](support-bundle.md) - Generate a support bundle
###### Auto generated by spf13/cobra on 31-Aug-2023
###### Auto generated by spf13/cobra on 25-Jan-2024
+1 -1
View File
@@ -27,4 +27,4 @@ support-bundle version [flags]
* [support-bundle](support-bundle.md) - Generate a support bundle
###### Auto generated by spf13/cobra on 31-Aug-2023
###### Auto generated by spf13/cobra on 25-Jan-2024
@@ -0,0 +1,37 @@
apiVersion: troubleshoot.sh/v1beta2
kind: HostCollector
metadata:
name: run-host-cmd-and-save-output
spec:
collectors:
- run:
collectorName: "my-custom-run"
command: "sh"
# this is for demonstration purpose only -- you probably don't want to drop your input to the bundle!
args:
- "-c"
- "cat $TS_INPUT_DIR/dummy.yaml > $TS_OUTPUT_DIR/dummy_content.yaml"
outputDir: "myCommandOutputs"
env:
- AWS_REGION=us-west-1
# if ignoreParentEnvs is true, it will not inherit envs from parent process.
# values specified in inheritEnv will not be used either
# ignoreParentEnvs: true
inheritEnvs:
- USER
input:
dummy.conf: |-
[hello]
hello = 1
[bye]
bye = 2
dummy.yaml: |-
username: postgres
password: <my-pass>
dbHost: <hostname>
map:
key: value
list:
- val1
- val2
+6
View File
@@ -72,6 +72,12 @@ spec:
- pass:
when: "== k3s"
message: K3S is a supported distribution
- pass:
when: "== oke"
message: OKE is a supported distribution
- pass:
when: "== kind"
message: Kind is a supported distribution
- warn:
message: Unable to determine the distribution of Kubernetes
- nodeResources:
+30 -32
View File
@@ -1,6 +1,6 @@
module helm-template
go 1.20
go 1.22.3
// Always use the local version of troubleshoot so as to build using
// the latest version of the library. This will ensure the example
@@ -9,29 +9,28 @@ replace github.com/replicatedhq/troubleshoot v0.0.0 => ../../../
require (
github.com/replicatedhq/troubleshoot v0.0.0
helm.sh/helm/v3 v3.12.3
sigs.k8s.io/yaml v1.3.0
helm.sh/helm/v3 v3.15.3
sigs.k8s.io/yaml v1.4.0
)
require (
github.com/BurntSushi/toml v1.2.1 // indirect
github.com/BurntSushi/toml v1.3.2 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.2.1 // indirect
github.com/Masterminds/sprig/v3 v3.2.3 // indirect
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
github.com/cyphar/filepath-securejoin v0.2.5 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/emicklei/go-restful/v3 v3.10.2 // indirect
github.com/go-logr/logr v1.2.4 // indirect
github.com/go-openapi/jsonpointer v0.19.6 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/swag v0.22.3 // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/jsonreference v0.21.0 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/uuid v1.3.1 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/huandu/xstrings v1.4.0 // indirect
github.com/imdario/mergo v0.3.15 // indirect
github.com/josharian/intern v1.0.0 // indirect
@@ -44,30 +43,29 @@ require (
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/shopspring/decimal v1.3.1 // indirect
github.com/spf13/cast v1.5.1 // indirect
github.com/spf13/cast v1.6.0 // 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
golang.org/x/crypto v0.14.0 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/oauth2 v0.12.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/term v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect
golang.org/x/time v0.3.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.31.0 // indirect
golang.org/x/crypto v0.25.0 // indirect
golang.org/x/net v0.27.0 // indirect
golang.org/x/oauth2 v0.20.0 // indirect
golang.org/x/sys v0.22.0 // indirect
golang.org/x/term v0.22.0 // indirect
golang.org/x/text v0.16.0 // indirect
golang.org/x/time v0.5.0 // indirect
google.golang.org/protobuf v1.33.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/api v0.28.2 // indirect
k8s.io/apiextensions-apiserver v0.28.1 // indirect
k8s.io/apimachinery v0.28.2 // indirect
k8s.io/client-go v0.28.2 // 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
sigs.k8s.io/controller-runtime v0.16.2 // indirect
k8s.io/api v0.30.2 // indirect
k8s.io/apiextensions-apiserver v0.30.2 // indirect
k8s.io/apimachinery v0.30.2 // indirect
k8s.io/client-go v0.30.2 // indirect
k8s.io/klog/v2 v2.130.1 // indirect
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect
k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect
sigs.k8s.io/controller-runtime v0.18.4 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
)
+79 -86
View File
@@ -1,5 +1,5 @@
github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
@@ -7,46 +7,47 @@ github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0
github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA=
github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
github.com/cyphar/filepath-securejoin v0.2.5 h1:6iR5tXJ/e6tJZzzdMc1km3Sa7RRIVBKAK32O2s7AYfo=
github.com/cyphar/filepath-securejoin v0.2.5/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/emicklei/go-restful/v3 v3.10.2 h1:hIovbnmBTLjHXkqEBUz3HGpXZdM7ZrE9fJIZIqlJLqE=
github.com/emicklei/go-restful/v3 v3.10.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY=
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g=
github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ2tG6yudJd8LBksgI=
github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ=
github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4=
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec=
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU=
github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
@@ -59,10 +60,8 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
@@ -80,31 +79,31 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA=
github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU=
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8=
github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs=
github.com/onsi/gomega v1.32.0 h1:JRYU78fJ1LPxlckP6Txi/EYqJvjtMrDC04/MM5XRHPk=
github.com/onsi/gomega v1.32.0/go.mod h1:a4x4gW6Pz2yK1MAmvluYme5lvYTn61afQ2ETw/8n4Lg=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA=
github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48=
github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
@@ -120,23 +119,22 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/oauth2 v0.12.0 h1:smVPGxink+n1ZI5pkQa8y6fZT0RW0MgCO5bFpepy4B4=
golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba4=
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo=
golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -149,38 +147,34 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk=
golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
@@ -191,30 +185,29 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
helm.sh/helm/v3 v3.12.3 h1:5y1+Sbty12t48T/t/CGNYUIME5BJ0WKfmW/sobYqkFg=
helm.sh/helm/v3 v3.12.3/go.mod h1:KPKQiX9IP5HX7o5YnnhViMnNuKiL/lJBVQ47GHe1R0k=
k8s.io/api v0.28.2 h1:9mpl5mOb6vXZvqbQmankOfPIGiudghwCoLl1EYfUZbw=
k8s.io/api v0.28.2/go.mod h1:RVnJBsjU8tcMq7C3iaRSGMeaKt2TWEUXcpIt/90fjEg=
k8s.io/apiextensions-apiserver v0.28.1 h1:l2ThkBRjrWpw4f24uq0Da2HaEgqJZ7pcgiEUTKSmQZw=
k8s.io/apiextensions-apiserver v0.28.1/go.mod h1:sVvrI+P4vxh2YBBcm8n2ThjNyzU4BQGilCQ/JAY5kGs=
k8s.io/apimachinery v0.28.2 h1:KCOJLrc6gu+wV1BYgwik4AF4vXOlVJPdiqn0yAWWwXQ=
k8s.io/apimachinery v0.28.2/go.mod h1:RdzF87y/ngqk9H4z3EL2Rppv5jj95vGS/HaFXrLDApU=
k8s.io/client-go v0.28.2 h1:DNoYI1vGq0slMBN/SWKMZMw0Rq+0EQW6/AK4v9+3VeY=
k8s.io/client-go v0.28.2/go.mod h1:sMkApowspLuc7omj1FOSUxSoqjr+d5Q0Yc0LOFnYFJY=
k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg=
k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ=
k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM=
k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 h1:qY1Ad8PODbnymg2pRbkyMT/ylpTrCM8P2RJ0yroCyIk=
k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
sigs.k8s.io/controller-runtime v0.16.2 h1:mwXAVuEk3EQf478PQwQ48zGOXvW27UJc8NHktQVuIPU=
sigs.k8s.io/controller-runtime v0.16.2/go.mod h1:vpMu3LpI5sYWtujJOa2uPK61nB5rbwlN7BAB8aSLvGU=
helm.sh/helm/v3 v3.15.3 h1:HcZDaVFe9uHa6hpsR54mJjYyRy4uz/pc6csg27nxFOc=
helm.sh/helm/v3 v3.15.3/go.mod h1:FzSIP8jDQaa6WAVg9F+OkKz7J0ZmAga4MABtTbsb9WQ=
k8s.io/api v0.30.2 h1:+ZhRj+28QT4UOH+BKznu4CBgPWgkXO7XAvMcMl0qKvI=
k8s.io/api v0.30.2/go.mod h1:ULg5g9JvOev2dG0u2hig4Z7tQ2hHIuS+m8MNZ+X6EmI=
k8s.io/apiextensions-apiserver v0.30.2 h1:l7Eue2t6QiLHErfn2vwK4KgF4NeDgjQkCXtEbOocKIE=
k8s.io/apiextensions-apiserver v0.30.2/go.mod h1:lsJFLYyK40iguuinsb3nt+Sj6CmodSI4ACDLep1rgjw=
k8s.io/apimachinery v0.30.2 h1:fEMcnBj6qkzzPGSVsAZtQThU62SmQ4ZymlXRC5yFSCg=
k8s.io/apimachinery v0.30.2/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc=
k8s.io/client-go v0.30.2 h1:sBIVJdojUNPDU/jObC+18tXWcTJVcwyqS9diGdWHk50=
k8s.io/client-go v0.30.2/go.mod h1:JglKSWULm9xlJLx4KCkfLLQ7XwtlbflV6uFFSHTMgVs=
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag=
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98=
k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI=
k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
sigs.k8s.io/controller-runtime v0.18.4 h1:87+guW1zhvuPLh1PHybKdYFLU0YJp4FhJRmiHvm5BZw=
sigs.k8s.io/controller-runtime v0.18.4/go.mod h1:TVoGrfdpbA9VRFaRnKgk9P5/atA0pMwq+f+msb9M8Sg=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=
sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E=
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4=
sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08=
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
+132 -122
View File
@@ -1,60 +1,68 @@
module github.com/replicatedhq/troubleshoot
go 1.20
go 1.22.4
toolchain go1.22.5
require (
github.com/ahmetalpbalkan/go-cursor v0.0.0-20131010032410-8136607ea412
github.com/apparentlymart/go-cidr v1.1.0
github.com/blang/semver/v4 v4.0.0
github.com/containers/image/v5 v5.25.0
github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2
github.com/fatih/color v1.15.0
github.com/go-logr/logr v1.2.4
github.com/cilium/ebpf v0.16.0
github.com/containerd/cgroups/v3 v3.0.3
github.com/containers/image/v5 v5.32.1
github.com/distribution/distribution/v3 v3.0.0-beta.1
github.com/fatih/color v1.17.0
github.com/go-logr/logr v1.4.2
github.com/go-redis/redis/v7 v7.4.1
github.com/go-sql-driver/mysql v1.7.1
github.com/go-sql-driver/mysql v1.8.1
github.com/gobwas/glob v0.2.3
github.com/godbus/dbus/v5 v5.1.0
github.com/google/gofuzz v1.2.0
github.com/google/uuid v1.3.1
github.com/gorilla/handlers v1.5.1
github.com/hashicorp/go-getter v1.7.2
github.com/google/uuid v1.6.0
github.com/gorilla/handlers v1.5.2
github.com/hashicorp/go-getter v1.7.5
github.com/hashicorp/go-multierror v1.1.1
github.com/jackc/pgx/v5 v5.4.3
github.com/jackc/pgx/v5 v5.6.0
github.com/longhorn/go-iscsi-helper v0.0.0-20210330030558-49a327fb024e
github.com/manifoldco/promptui v0.9.0
github.com/mattn/go-isatty v0.0.19
github.com/mattn/go-isatty v0.0.20
github.com/mholt/archiver/v3 v3.5.1
github.com/microsoft/go-mssqldb v1.6.0
github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b
github.com/microsoft/go-mssqldb v1.7.2
github.com/opencontainers/image-spec v1.1.0
github.com/pkg/errors v0.9.1
github.com/replicatedhq/termui/v3 v3.1.1-0.20200811145416-f40076d26851
github.com/segmentio/ksuid v1.0.4
github.com/shirou/gopsutil/v3 v3.23.9
github.com/spf13/cobra v1.7.0
github.com/shirou/gopsutil/v3 v3.24.5
github.com/spf13/cobra v1.8.1
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.17.0
github.com/stretchr/testify v1.8.4
github.com/spf13/viper v1.19.0
github.com/stretchr/testify v1.9.0
github.com/tj/go-spin v1.1.0
go.opentelemetry.io/otel v1.18.0
go.opentelemetry.io/otel/sdk v1.18.0
golang.org/x/exp v0.0.0-20230905200255-921286631fa9
golang.org/x/sync v0.3.0
github.com/vmware-tanzu/velero v1.14.0
go.opentelemetry.io/otel v1.28.0
go.opentelemetry.io/otel/sdk v1.28.0
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8
golang.org/x/mod v0.20.0
golang.org/x/sync v0.8.0
gopkg.in/yaml.v2 v2.4.0
k8s.io/api v0.28.2
k8s.io/apiextensions-apiserver v0.28.1
k8s.io/apimachinery v0.28.2
k8s.io/apiserver v0.28.1
k8s.io/cli-runtime v0.28.2
k8s.io/client-go v0.28.2
k8s.io/klog/v2 v2.100.1
oras.land/oras-go v1.2.3
sigs.k8s.io/controller-runtime v0.16.2
sigs.k8s.io/e2e-framework v0.3.0
k8s.io/api v0.30.3
k8s.io/apiextensions-apiserver v0.30.3
k8s.io/apimachinery v0.30.3
k8s.io/apiserver v0.30.3
k8s.io/cli-runtime v0.30.3
k8s.io/client-go v0.30.3
k8s.io/klog/v2 v2.130.1
oras.land/oras-go v1.2.6
sigs.k8s.io/controller-runtime v0.18.5
sigs.k8s.io/e2e-framework v0.4.0
)
require (
cloud.google.com/go/compute/metadata v0.2.3 // indirect
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 // indirect
cloud.google.com/go/compute/metadata v0.3.0 // indirect
dario.cat/mergo v1.0.0 // indirect
filippo.io/edwards25519 v1.1.0 // indirect
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // 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
@@ -62,18 +70,25 @@ require (
github.com/Masterminds/squirrel v1.5.4 // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/chai2010/gettext-go v1.0.2 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/docker/distribution v2.8.2+incompatible // indirect
github.com/emicklei/go-restful/v3 v3.10.2 // indirect
github.com/evanphx/json-patch/v5 v5.6.0 // indirect
github.com/containerd/errdefs v0.1.0 // indirect
github.com/containerd/log v0.1.0 // indirect
github.com/containerd/platforms v0.2.1 // indirect
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect
github.com/distribution/reference v0.6.0 // indirect
github.com/docker/distribution v2.8.3+incompatible // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
github.com/evanphx/json-patch/v5 v5.9.0 // indirect
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect
github.com/go-gorp/gorp/v3 v3.0.5 // indirect
github.com/go-gorp/gorp/v3 v3.1.0 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
github.com/golang-sql/sqlexp v0.1.0 // indirect
github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/go-containerregistry v0.20.0 // indirect
github.com/google/s2a-go v0.1.7 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.1 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/gosuri/uitable v0.0.4 // indirect
github.com/huandu/xstrings v1.4.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
@@ -83,173 +98,168 @@ require (
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
github.com/lib/pq v1.10.9 // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/mistifyio/go-zfs/v3 v3.0.0 // indirect
github.com/mistifyio/go-zfs/v3 v3.0.1 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/onsi/ginkgo v1.14.0 // indirect
github.com/moby/docker-image-spec v1.3.1 // indirect
github.com/moby/sys/user v0.2.0 // indirect
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
github.com/rubenv/sql-migrate v1.3.1 // indirect
github.com/rubenv/sql-migrate v1.5.2 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sagikazarmark/locafero v0.3.0 // indirect
github.com/sagikazarmark/locafero v0.4.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/shoenig/go-m1cpu v0.1.6 // indirect
github.com/shopspring/decimal v1.3.1 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/sylabs/sif/v2 v2.11.1 // indirect
github.com/sylabs/sif/v2 v2.18.0 // indirect
github.com/tchap/go-patricia/v2 v2.3.1 // indirect
github.com/vladimirvivien/gexe v0.2.0 // 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
go.opentelemetry.io/otel/metric v1.18.0 // indirect
go.opentelemetry.io/otel/trace v1.18.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect
go.opentelemetry.io/otel/metric v1.28.0 // indirect
go.opentelemetry.io/otel/trace v1.28.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/mod v0.12.0 // indirect
golang.org/x/tools v0.13.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 // indirect
k8s.io/component-base v0.28.1 // indirect
k8s.io/kubectl v0.28.1 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda // indirect
k8s.io/component-base v0.30.3 // indirect
k8s.io/kubectl v0.30.0 // indirect
)
require (
cloud.google.com/go v0.110.7 // indirect
cloud.google.com/go/compute v1.23.0 // indirect
cloud.google.com/go/iam v1.1.1 // indirect
cloud.google.com/go/storage v1.30.1 // indirect
cloud.google.com/go v0.112.1 // indirect
cloud.google.com/go/iam v1.1.7 // indirect
cloud.google.com/go/storage v1.40.0 // indirect
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
github.com/BurntSushi/toml v1.2.1 // indirect
github.com/Microsoft/go-winio v0.6.0 // indirect
github.com/Microsoft/hcsshim v0.10.0-rc.7 // indirect
github.com/BurntSushi/toml v1.4.0 // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/Microsoft/hcsshim v0.12.5 // indirect
github.com/andybalholm/brotli v1.0.1 // indirect
github.com/aws/aws-sdk-go v1.44.198 // indirect
github.com/aws/aws-sdk-go v1.48.10 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
github.com/c9s/goprocinfo v0.0.0-20170724085704-0010a05ce49f // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/chzyer/readline v1.5.1 // indirect
github.com/containerd/cgroups v1.1.0 // indirect
github.com/containerd/containerd v1.7.0 // indirect
github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect
github.com/containerd/containerd v1.7.20 // indirect
github.com/containerd/stargz-snapshotter/estargz v0.15.1 // indirect
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 // indirect
github.com/containers/ocicrypt v1.1.7 // indirect
github.com/containers/storage v1.46.0 // indirect
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
github.com/containers/ocicrypt v1.2.0 // indirect
github.com/containers/storage v1.55.0 // indirect
github.com/cyphar/filepath-securejoin v0.3.1 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/docker/cli v23.0.1+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/cli v27.1.1+incompatible // indirect
github.com/docker/docker v27.1.1+incompatible // indirect
github.com/docker/docker-credential-helpers v0.8.2 // indirect
github.com/docker/go-connections v0.5.0 // indirect
github.com/docker/go-metrics v0.0.1 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect
github.com/evanphx/json-patch v5.6.0+incompatible // indirect
github.com/felixge/httpsnoop v1.0.3 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/evanphx/json-patch v5.7.0+incompatible // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/go-errors/errors v1.4.2 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-openapi/jsonpointer v0.19.6 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/swag v0.22.3 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/jsonreference v0.21.0 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/btree v1.0.1 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/go-intervals v0.0.2 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/googleapis/gax-go/v2 v2.12.0 // indirect
github.com/gorilla/mux v1.8.0 // indirect
github.com/googleapis/gax-go/v2 v2.12.3 // indirect
github.com/gorilla/mux v1.8.1 // indirect
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-safetemp v1.0.0 // indirect
github.com/hashicorp/go-version v1.6.0
github.com/hashicorp/go-version v1.7.0
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/imdario/mergo v0.3.15 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jmespath/go-jmespath v0.4.0 // 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/pgzip v1.2.6-0.20220930104621-17e8dac29df8 // indirect
github.com/klauspost/compress v1.17.9 // indirect
github.com/klauspost/pgzip v1.2.6 // indirect
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-runewidth v0.0.14 // indirect
github.com/mattn/go-shellwords v1.0.12 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
github.com/mitchellh/go-wordwrap v1.0.1
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/moby/locker v1.0.1 // indirect
github.com/moby/spdystream v0.2.0 // indirect
github.com/moby/sys/mountinfo v0.6.2 // indirect
github.com/moby/term v0.0.0-20221205130635-1aeaba878587 // indirect
github.com/moby/sys/mountinfo v0.7.2 // indirect
github.com/moby/term v0.5.0 // 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/nsf/termbox-go v0.0.0-20190121233118-02980233997d // indirect
github.com/nwaples/rardecode v1.1.2 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/runc v1.1.5 // indirect
github.com/opencontainers/runtime-spec v1.1.0-rc.1 // indirect
github.com/opencontainers/runtime-spec v1.2.0
github.com/opencontainers/selinux v1.11.0 // indirect
github.com/ostreedev/ostree-go v0.0.0-20210805093236-719684c64e4f // indirect
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/pierrec/lz4/v4 v4.1.2 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_golang v1.16.0 // indirect
github.com/prometheus/client_model v0.4.0 // indirect
github.com/prometheus/common v0.44.0 // indirect
github.com/prometheus/procfs v0.10.1 // indirect
github.com/rivo/uniseg v0.4.4 // indirect
github.com/spf13/afero v1.10.0 // indirect
github.com/spf13/cast v1.5.1 // indirect
github.com/prometheus/client_golang v1.19.0 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.52.3 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/spf13/afero v1.11.0 // indirect
github.com/spf13/cast v1.6.0 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/ulikunitz/xz v0.5.11 // indirect
github.com/vbatts/tar-split v0.11.3 // indirect
github.com/ulikunitz/xz v0.5.12 // indirect
github.com/vbatts/tar-split v0.11.5 // indirect
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
github.com/xlab/treeprint v1.2.0 // indirect
github.com/yusufpapurcu/wmi v1.2.3 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
go.opencensus.io v0.24.0 // indirect
go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect
golang.org/x/crypto v0.14.0 // indirect
golang.org/x/net v0.17.0
golang.org/x/oauth2 v0.12.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/term v0.13.0 // indirect
golang.org/x/text v0.13.0
golang.org/x/time v0.3.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/api v0.143.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20230913181813-007df8e322eb // indirect
google.golang.org/grpc v1.58.2 // indirect
google.golang.org/protobuf v1.31.0 // indirect
golang.org/x/crypto v0.26.0 // indirect
golang.org/x/net v0.28.0
golang.org/x/oauth2 v0.22.0 // indirect
golang.org/x/sys v0.24.0
golang.org/x/term v0.23.0 // indirect
golang.org/x/text v0.17.0
golang.org/x/time v0.5.0 // indirect
google.golang.org/api v0.172.0 // indirect
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect
google.golang.org/grpc v1.64.1 // indirect
google.golang.org/protobuf v1.33.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
helm.sh/helm/v3 v3.12.3
k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect
k8s.io/metrics v0.28.2
k8s.io/utils v0.0.0-20230406110748-d93618cff8a2
helm.sh/helm/v3 v3.15.3
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect
k8s.io/kubelet v0.30.3
k8s.io/metrics v0.30.3
k8s.io/utils v0.0.0-20230726121419-3b25d923346b
periph.io/x/host/v3 v3.8.2
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/structured-merge-diff/v4 v4.2.3 // indirect
sigs.k8s.io/yaml v1.3.0
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
sigs.k8s.io/yaml v1.4.0
)
replace (
+372 -508
View File
File diff suppressed because it is too large Load Diff
+109 -10
View File
@@ -78,6 +78,7 @@ func LoadFromCLIArgs(ctx context.Context, client kubernetes.Interface, args []st
ctx = context.Background()
}
var kindsFromURL *loader.TroubleshootKinds
rawSpecs := []string{}
for _, v := range args {
@@ -167,25 +168,42 @@ func LoadFromCLIArgs(ctx context.Context, client kubernetes.Interface, args []st
rawSpecs = append(rawSpecs, content...)
} else {
if !util.IsURL(v) {
return nil, types.NewExitCodeError(constants.EXIT_CODE_SPEC_ISSUES, fmt.Errorf("%s is not a URL and was not found (err %s)", v, err))
return nil, types.NewExitCodeError(constants.EXIT_CODE_SPEC_ISSUES, fmt.Errorf("%s is not a URL and was not found", v))
}
// Download preflight specs
rawSpec, err := downloadFromHttpURL(ctx, v, map[string]string{"User-Agent": "Replicated_Preflight/v1beta2"})
parsedURL, err := url.ParseRequestURI(v)
if err != nil {
return nil, err
return nil, types.NewExitCodeError(constants.EXIT_CODE_SPEC_ISSUES, err)
}
rawSpecs = append(rawSpecs, rawSpec)
// Download support bundle specs
rawSpec, err = downloadFromHttpURL(ctx, v, map[string]string{
"User-Agent": "Replicated_Troubleshoot/v1beta1",
"Bundle-Upload-Host": fmt.Sprintf("%s://%s", u.Scheme, u.Host),
var specFromURL string
if parsedURL.Host == "kots.io" {
// To download specs from kots.io, we need to set the User-Agent header
specFromURL, err = downloadFromHttpURL(ctx, v, map[string]string{
"User-Agent": "Replicated_Troubleshoot/v1beta1",
})
if err != nil {
return nil, err
}
} else {
specFromURL, err = downloadFromHttpURL(ctx, v, nil)
if err != nil {
return nil, err
}
}
// load URL spec first to remove URI key from the spec
kindsFromURL, err = loader.LoadSpecs(ctx, loader.LoadOptions{
RawSpec: specFromURL,
})
if err != nil {
return nil, err
}
rawSpecs = append(rawSpecs, rawSpec)
// remove URI key from the spec if any
for i := range kindsFromURL.SupportBundlesV1Beta2 {
kindsFromURL.SupportBundlesV1Beta2[i].Spec.Uri = ""
}
}
}
}
@@ -196,6 +214,9 @@ func LoadFromCLIArgs(ctx context.Context, client kubernetes.Interface, args []st
if err != nil {
return nil, err
}
if kindsFromURL != nil {
kinds.Add(kindsFromURL)
}
if vp.GetBool("load-cluster-specs") {
clusterKinds, err := LoadFromCluster(ctx, client, vp.GetStringSlice("selector"), vp.GetString("namespace"))
@@ -340,3 +361,81 @@ func LoadFromCluster(ctx context.Context, client kubernetes.Interface, selectors
RawSpecs: rawSpecs,
})
}
// LoadAdditionalSpecFromURIs loads additional specs from the URIs provided in the kinds.
// This function will modify kinds in place.
func LoadAdditionalSpecFromURIs(ctx context.Context, kinds *loader.TroubleshootKinds) {
obj := reflect.ValueOf(*kinds)
// iterate over all fields of the TroubleshootKinds
// e.g. SupportBundlesV1Beta2, PreflightsV1Beta2, etc.
for i := 0; i < obj.NumField(); i++ {
field := obj.Field(i)
if field.Kind() != reflect.Slice {
continue
}
// look at each spec in the slice
// e.g. each spec in []PreflightsV1Beta2
for count := 0; count < field.Len(); count++ {
currentSpec := field.Index(count)
specName := currentSpec.Type().Name()
// check if .Spec.Uri exists
specField := currentSpec.FieldByName("Spec")
if !specField.IsValid() {
continue
}
uriField := specField.FieldByName("Uri")
if uriField.Kind() != reflect.String {
continue
}
// download spec from URI
uri := uriField.String()
if uri == "" {
continue
}
rawSpec, err := downloadFromHttpURL(ctx, uri, nil)
if err != nil {
klog.Warningf("failed to download spec from URI %q: %v", uri, err)
continue
}
// load spec from raw spec
uriKinds, err := loader.LoadSpecs(ctx, loader.LoadOptions{RawSpec: string(rawSpec)})
if err != nil {
klog.Warningf("failed to load spec from URI %q: %v", uri, err)
continue
}
// replace original spec with the loaded spec from URI
newSpec := getFirstSpecOf(uriKinds, specName)
if !newSpec.IsValid() {
klog.Warningf("failed to read spec of type %s in URI %s", specName, uri)
continue
}
currentSpec.Set(newSpec)
}
}
}
// dynamically get spec from kinds of given name
// return first element of the spec slice
func getFirstSpecOf(kinds *loader.TroubleshootKinds, name string) reflect.Value {
obj := reflect.ValueOf(*kinds)
for i := 0; i < obj.NumField(); i++ {
field := obj.Field(i)
if field.Kind() != reflect.Slice {
continue
}
if field.Len() > 0 {
if field.Index(0).Type().Name() == name {
// return first element
return field.Index(0)
}
}
}
return reflect.Value{}
}
+59
View File
@@ -3,6 +3,8 @@ package specs
import (
"context"
"fmt"
"net/http"
"net/http/httptest"
"reflect"
"testing"
@@ -10,6 +12,7 @@ import (
"github.com/replicatedhq/troubleshoot/internal/testutils"
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
"github.com/replicatedhq/troubleshoot/pkg/loader"
"github.com/spf13/viper"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
corev1 "k8s.io/api/core/v1"
@@ -201,3 +204,59 @@ spec:
},
}
}
func TestLoadFromURI(t *testing.T) {
m := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(`apiVersion: troubleshoot.sh/v1beta2
apiVersion: troubleshoot.sh/v1beta2
kind: HostCollector
metadata:
name: cpu
spec:
collectors:
- cpu: {}
`))
}))
defer m.Close()
client := testclient.NewSimpleClientset()
specs, err := LoadFromCLIArgs(context.Background(), client, []string{m.URL}, viper.New())
require.NoError(t, err)
require.Len(t, specs.HostCollectorsV1Beta2, 1)
}
func TestLoadAdditionalSpecFromURIs(t *testing.T) {
m := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(`apiVersion: troubleshoot.sh/v1beta2
apiVersion: troubleshoot.sh/v1beta2
kind: Preflight
metadata:
name: preflight-2
spec:
collectors:
- ceph: {}
`))
}))
defer m.Close()
kinds := loader.NewTroubleshootKinds()
kinds.PreflightsV1Beta2 = []troubleshootv1beta2.Preflight{
{
ObjectMeta: metav1.ObjectMeta{
Name: "preflight-1",
},
Spec: troubleshootv1beta2.PreflightSpec{
Uri: m.URL,
Collectors: []*troubleshootv1beta2.Collect{
{
DNS: &troubleshootv1beta2.DNS{},
},
},
},
},
}
LoadAdditionalSpecFromURIs(context.Background(), kinds)
require.Len(t, kinds.PreflightsV1Beta2, 1)
require.Len(t, kinds.PreflightsV1Beta2[0].Spec.Collectors, 1)
require.NotNil(t, kinds.PreflightsV1Beta2[0].Spec.Collectors[0].Ceph)
}
+28 -7
View File
@@ -15,16 +15,25 @@ import (
func GetTestFixture(t *testing.T, path string) string {
t.Helper()
p := path
if !filepath.IsAbs(path) {
p = filepath.Join("../../testdata", path)
}
b, err := os.ReadFile(p)
b, err := os.ReadFile(TestFixtureFilePath(t, path))
require.NoError(t, err)
return string(b)
}
// FileDir returns the directory of the current source file.
func TestFixtureFilePath(t *testing.T, path string) string {
t.Helper()
if !filepath.IsAbs(path) {
p, err := filepath.Abs(filepath.Join(FileDir(), "../../testdata", path))
require.NoError(t, err)
return p
} else {
return path
}
}
// FileDir returns the directory of this source file
func FileDir() string {
_, filename, _, _ := runtime.Caller(0)
return filepath.Dir(filename)
@@ -32,9 +41,13 @@ func FileDir() string {
// Generates a temporary filename
func TempFilename(prefix string) string {
return filepath.Join(os.TempDir(), generateTempName(prefix))
}
func generateTempName(prefix string) string {
randBytes := make([]byte, 16)
rand.Read(randBytes)
return filepath.Join(os.TempDir(), fmt.Sprintf("%s_%s", prefix, hex.EncodeToString(randBytes)))
return fmt.Sprintf("%s_%s", prefix, hex.EncodeToString(randBytes))
}
func CreateTestFile(t *testing.T, path string) {
@@ -69,3 +82,11 @@ func AsJSON(t *testing.T, v interface{}) string {
return string(b)
}
}
func ServeFromFilePath(t *testing.T, data string) string {
t.Helper()
path := filepath.Join(t.TempDir(), generateTempName("testfile"))
CreateTestFileWithData(t, path, data)
return path
}
+117
View File
@@ -1,14 +1,22 @@
package util
import (
"bufio"
"bytes"
"encoding/json"
"fmt"
"net/url"
"os"
"os/user"
"strings"
"text/template"
"golang.org/x/text/cases"
"golang.org/x/text/language"
)
const HOST_COLLECTORS_RUN_AS_ROOT_PROMPT = "Some host collectors need to be run as root.\nDo you want to exit and rerun the command using sudo?"
func HomeDir() string {
if h := os.Getenv("HOME"); h != "" {
return h
@@ -52,3 +60,112 @@ func EstimateNumberOfLines(text string) int {
}
return n
}
// Append appends elements in src to target.
// We have this function because of how the
// builtin append() function works. It treats
// target nil slices the same as empty slices.
func Append[T any](target []T, src []T) []T {
// Do nothing only if src is nil
if src == nil {
return target
}
// In case target is nil, we need to initialize it
// since append() will not do it for us when len(src) == 0
if target == nil {
target = []T{}
}
return append(target, src...)
}
// IsInCluster returns true if the code is running within a process
// inside a kubernetes pod
func IsInCluster() bool {
// This is a best effort check, it's not guaranteed to be accurate
host, port := os.Getenv("KUBERNETES_SERVICE_HOST"), os.Getenv("KUBERNETES_SERVICE_PORT")
if len(host) == 0 || len(port) == 0 {
return false
}
return true
}
// RenderTemplate renders a template and returns the result as a string
func RenderTemplate(tpl string, data interface{}) (string, error) {
// Create a new template and parse the letter into it
t, err := template.New("data").Parse(tpl)
if err != nil {
return "", err
}
// Create a new buffer
buf := new(bytes.Buffer)
// Execute the template and write the bytes to the buffer
err = t.Execute(buf, data)
if err != nil {
return "", err
}
// Return the string representation of the buffer
return buf.String(), nil
}
func IsRunningAsRoot() bool {
currentUser, err := user.Current()
if err != nil {
return false
}
// Check if the user ID is 0 (root's UID)
return currentUser.Uid == "0"
}
func PromptYesNo(question string) bool {
reader := bufio.NewReader(os.Stdin)
for {
fmt.Printf("%s (yes/no): ", question)
response, err := reader.ReadString('\n')
if err != nil {
fmt.Println("Error reading response:", err)
continue
}
response = strings.TrimSpace(response)
response = strings.ToLower(response)
if response == "yes" || response == "y" {
return true
} else if response == "no" || response == "n" {
return false
} else {
fmt.Println("Please type 'yes' or 'no'.")
}
}
}
func Dedup[T any](objs []T) []T {
seen := make(map[string]bool)
out := []T{}
if len(objs) == 0 {
return objs
}
for _, o := range objs {
data, err := json.Marshal(o)
if err != nil {
out = append(out, o)
continue
}
key := string(data)
if _, ok := seen[key]; !ok {
out = append(out, o)
seen[key] = true
}
}
return out
}
+108
View File
@@ -194,3 +194,111 @@ func Test_EstimateNumberOfLines(t *testing.T) {
})
}
}
func TestAppend(t *testing.T) {
tests := []struct {
name string
target []string
src []string
want []string
}{
{
name: "empty target",
target: []string{},
src: []string{"a", "b", "c"},
want: []string{"a", "b", "c"},
},
{
name: "empty src",
target: []string{"a", "b", "c"},
src: []string{},
want: []string{"a", "b", "c"},
},
{
name: "non-empty target and src",
target: []string{"a", "b", "c"},
src: []string{"d", "e", "f"},
want: []string{"a", "b", "c", "d", "e", "f"},
},
{
name: "nil target",
target: nil,
src: []string{"a", "b", "c"},
want: []string{"a", "b", "c"},
},
{
name: "nil src",
target: []string{"a", "b", "c"},
src: nil,
want: []string{"a", "b", "c"},
},
{
name: "nil target and empty src",
target: nil,
src: []string{},
want: []string{},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := Append(tt.target, tt.src)
assert.Equal(t, tt.want, got, "Append() = %v, want %v", got, tt.want)
})
}
}
func TestRenderTemplate(t *testing.T) {
tests := []struct {
name string
tpl string
data interface{}
want string
wantErr bool
}{
{
name: "empty template and data",
tpl: "",
data: nil,
want: "",
wantErr: false,
},
{
name: "empty template with data",
tpl: "",
data: map[string]string{"Name": "World"},
want: "",
wantErr: false,
},
{
name: "empty data with template with no keys",
tpl: "Hello, World!",
data: nil,
want: "Hello, World!",
wantErr: false,
},
{
name: "simple template",
tpl: "Hello, {{ .Name }}!",
data: map[string]string{"Name": "World"},
want: "Hello, World!",
wantErr: false,
},
{
name: "template with missing key",
tpl: "Hello, {{ .Name }}!",
data: map[string]string{"Name2": "World"},
want: "Hello, <no value>!",
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := RenderTemplate(tt.tpl, tt.data)
if (err != nil) != tt.wantErr {
t.Errorf("RenderTemplate() error = %v, wantErr %v", err, tt.wantErr)
return
}
assert.Equal(t, tt.want, got, "RenderTemplate() = %v, want %v", got, tt.want)
})
}
}
+29
View File
@@ -1,16 +1,20 @@
package analyzer
import (
"bufio"
"bytes"
"context"
"encoding/json"
"fmt"
"reflect"
"strconv"
"strings"
"github.com/pkg/errors"
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
"github.com/replicatedhq/troubleshoot/pkg/constants"
"github.com/replicatedhq/troubleshoot/pkg/multitype"
"github.com/replicatedhq/troubleshoot/pkg/redact"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
@@ -226,6 +230,8 @@ func getAnalyzer(analyzer *troubleshootv1beta2.Analyze) Analyzer {
return &AnalyzeRedis{analyzer: analyzer.Redis}
case analyzer.CephStatus != nil:
return &AnalyzeCephStatus{analyzer: analyzer.CephStatus}
case analyzer.Velero != nil:
return &AnalyzeVelero{analyzer: analyzer.Velero}
case analyzer.Longhorn != nil:
return &AnalyzeLonghorn{analyzer: analyzer.Longhorn}
case analyzer.RegistryImages != nil:
@@ -238,6 +244,14 @@ func getAnalyzer(analyzer *troubleshootv1beta2.Analyze) Analyzer {
return &AnalyzeClusterResource{analyzer: analyzer.ClusterResource}
case analyzer.Certificates != nil:
return &AnalyzeCertificates{analyzer: analyzer.Certificates}
case analyzer.Goldpinger != nil:
return &AnalyzeGoldpinger{analyzer: analyzer.Goldpinger}
case analyzer.Event != nil:
return &AnalyzeEvent{analyzer: analyzer.Event}
case analyzer.NodeMetrics != nil:
return &AnalyzeNodeMetrics{analyzer: analyzer.NodeMetrics}
case analyzer.HTTP != nil:
return &AnalyzeHTTPAnalyze{analyzer: analyzer.HTTP}
default:
return nil
}
@@ -265,3 +279,18 @@ func DedupAnalyzers(allAnalyzers []*troubleshootv1beta2.Analyze) []*troubleshoot
}
return finalAnalyzers
}
func stripRedactedLines(yaml []byte) []byte {
buf := bytes.NewBuffer(yaml)
scanner := bufio.NewScanner(buf)
out := []byte{}
for scanner.Scan() {
line := strings.ReplaceAll(scanner.Text(), redact.MASK_TEXT, "HIDDEN")
out = append(out, []byte(line)...)
out = append(out, '\n')
}
return out
}
+11 -1
View File
@@ -42,7 +42,7 @@ func analyzeClusterVersion(analyzer *troubleshootv1beta2.ClusterVersion, getColl
return nil, errors.Wrap(err, "failed to parse cluster_version.json")
}
k8sVersion, err := semver.Make(strings.TrimLeft(collectorClusterVersion.String, "v"))
k8sVersion, err := parseK8sVersionString(collectorClusterVersion.String)
if err != nil {
return nil, errors.Wrap(err, "failed to parse semver from cluster_version.json")
}
@@ -58,6 +58,16 @@ func title(checkName string) string {
return checkName
}
func parseK8sVersionString(version string) (semver.Version, error) {
// Workaround for https://github.com/aws/containers-roadmap/issues/1404
// for EKS, replace pre-release gitVersion string with the release version
if strings.Contains(version, "-eks-") {
version = strings.Split(version, "-")[0]
}
return semver.Make(strings.TrimLeft(version, "v"))
}
func analyzeClusterVersionResult(k8sVersion semver.Version, outcomes []*troubleshootv1beta2.Outcome, checkName string) (*AnalyzeResult, error) {
for _, outcome := range outcomes {
when := ""
+39
View File
@@ -6,6 +6,7 @@ import (
"github.com/blang/semver/v4"
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
"github.com/stretchr/testify/assert"
)
func Test_analyzeClusterVersionResult(t *testing.T) {
@@ -103,3 +104,41 @@ func Test_analyzeClusterVersionResult(t *testing.T) {
})
}
}
func Test_parseVersionString(t *testing.T) {
tests := []struct {
name string
rawVersion string
want semver.Version
wantErr bool
}{
{
name: "valid version",
rawVersion: "1.17.0",
want: semver.MustParse("1.17.0"),
},
{
name: "valid version with v prefix",
rawVersion: "v1.17.0",
want: semver.MustParse("1.17.0"),
},
{
name: "invalid version",
rawVersion: "v1.17",
want: semver.Version{},
wantErr: true,
},
{
name: "EKS version",
rawVersion: "v1.25.16-eks-8cb36c9",
want: semver.MustParse("1.25.16"),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := parseK8sVersionString(tt.rawVersion)
assert.Equal(t, tt.wantErr, err != nil, "parseVersionString() error = %v, wantErr %v", err, tt.wantErr)
assert.Equal(t, tt.want, got, "parseVersionString() = %v, want %v", got, tt.want)
})
}
}
+34
View File
@@ -0,0 +1,34 @@
package analyzer
import "fmt"
type ComparisonOperator int
const (
Unknown ComparisonOperator = iota
Equal
NotEqual
GreaterThan
GreaterThanOrEqual
LessThan
LessThanOrEqual
)
func ParseComparisonOperator(s string) (ComparisonOperator, error) {
switch s {
case "=", "==", "===":
return Equal, nil
case "!=", "!==":
return NotEqual, nil
case "<":
return LessThan, nil
case ">":
return GreaterThan, nil
case "<=":
return LessThanOrEqual, nil
case ">=":
return GreaterThanOrEqual, nil
}
return Unknown, fmt.Errorf("unknown operator: %s", s)
}
+79
View File
@@ -0,0 +1,79 @@
package analyzer
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestParseComparisonOperator(t *testing.T) {
tests := []struct {
name string
input string
want ComparisonOperator
wantErr bool
}{
{
name: "equal",
input: "=",
want: Equal,
},
{
name: "equal",
input: "==",
want: Equal,
},
{
name: "equal",
input: "===",
want: Equal,
},
{
name: "not equal",
input: "!=",
want: NotEqual,
},
{
name: "not equal",
input: "!==",
want: NotEqual,
},
{
name: "less than",
input: "<",
want: LessThan,
},
{
name: "greater than",
input: ">",
want: GreaterThan,
},
{
name: "less than or equal",
input: "<=",
want: LessThanOrEqual,
},
{
name: "greater than or equal",
input: ">=",
want: GreaterThanOrEqual,
},
{
name: "invalid operator 1",
input: "",
wantErr: true,
},
{
name: "invalid operator 2",
input: "gibberish",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := ParseComparisonOperator(tt.input)
assert.Equal(t, tt.want, got, "ParseOperator() = %v, want %v", got, tt.want)
assert.Equalf(t, tt.wantErr, err != nil, "ParseOperator() error = %v, wantErr %v", err, tt.wantErr)
})
}
}
+74 -27
View File
@@ -13,38 +13,46 @@ import (
)
type providers struct {
microk8s bool
dockerDesktop bool
eks bool
gke bool
digitalOcean bool
openShift bool
tanzu bool
kurl bool
aks bool
ibm bool
minikube bool
rke2 bool
k3s bool
microk8s bool
dockerDesktop bool
eks bool
gke bool
digitalOcean bool
openShift bool
tanzu bool
kurl bool
aks bool
ibm bool
minikube bool
rke2 bool
k3s bool
oke bool
kind bool
k0s bool
embeddedCluster bool
}
type Provider int
const (
unknown Provider = iota
microk8s Provider = iota
dockerDesktop Provider = iota
eks Provider = iota
gke Provider = iota
digitalOcean Provider = iota
openShift Provider = iota
tanzu Provider = iota
kurl Provider = iota
aks Provider = iota
ibm Provider = iota
minikube Provider = iota
rke2 Provider = iota
k3s Provider = iota
unknown Provider = iota
microk8s Provider = iota
dockerDesktop Provider = iota
eks Provider = iota
gke Provider = iota
digitalOcean Provider = iota
openShift Provider = iota
tanzu Provider = iota
kurl Provider = iota
aks Provider = iota
ibm Provider = iota
minikube Provider = iota
rke2 Provider = iota
k3s Provider = iota
oke Provider = iota
kind Provider = iota
k0s Provider = iota
embeddedCluster Provider = iota
)
type AnalyzeDistribution struct {
@@ -125,6 +133,20 @@ func ParseNodesForProviders(nodes []corev1.Node) (providers, string) {
foundProviders.k3s = true
stringProvider = "k3s"
}
if k == "oci.oraclecloud.com/fault-domain" {
// Based on: https://docs.oracle.com/en-us/iaas/Content/ContEng/Reference/contengsupportedlabelsusecases.htm
foundProviders.oke = true
stringProvider = "oke"
}
if k == "node.k0sproject.io/role" {
foundProviders.k0s = true
stringProvider = "k0s"
}
if k == "kots.io/embedded-cluster-role" {
foundProviders.embeddedCluster = true
stringProvider = "embedded-cluster"
}
}
for k := range node.ObjectMeta.Annotations {
@@ -155,6 +177,10 @@ func ParseNodesForProviders(nodes []corev1.Node) (providers, string) {
foundProviders.ibm = true
stringProvider = "ibm"
}
if strings.HasPrefix(node.Spec.ProviderID, "kind:") {
foundProviders.kind = true
stringProvider = "kind"
}
}
if foundMaster {
@@ -165,6 +191,11 @@ func ParseNodesForProviders(nodes []corev1.Node) (providers, string) {
}
}
// If k0s and embedded-cluster are both found, prefer embedded-cluster
if foundProviders.k0s && foundProviders.embeddedCluster {
stringProvider = "embedded-cluster"
}
return foundProviders, stringProvider
}
@@ -326,6 +357,14 @@ func compareDistributionConditionalToActual(conditional string, actual providers
isMatch = actual.rke2
case k3s:
isMatch = actual.k3s
case oke:
isMatch = actual.oke
case kind:
isMatch = actual.kind
case k0s:
isMatch = actual.k0s
case embeddedCluster:
isMatch = actual.embeddedCluster
}
switch parts[0] {
@@ -366,6 +405,14 @@ func mustNormalizeDistributionName(raw string) Provider {
return rke2
case "k3s":
return k3s
case "oke":
return oke
case "kind":
return kind
case "k0s":
return k0s
case "embeddedcluster":
return embeddedCluster
}
return unknown
+131
View File
@@ -5,6 +5,8 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func Test_compareDistributionConditionalToActual(t *testing.T) {
@@ -39,6 +41,30 @@ func Test_compareDistributionConditionalToActual(t *testing.T) {
},
expected: true,
},
{
name: "== kind when kind is found",
conditional: "== kind",
input: providers{
kind: true,
},
expected: true,
},
{
name: "== k0s when k0s is found",
conditional: "== k0s",
input: providers{
k0s: true,
},
expected: true,
},
{
name: "== embedded-cluster when embedded-cluster is found",
conditional: "== embedded-cluster",
input: providers{
embeddedCluster: true,
},
expected: true,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
@@ -73,6 +99,66 @@ func Test_mustNormalizeDistributionName(t *testing.T) {
raw: "Docker-Desktop",
expected: dockerDesktop,
},
{
raw: "embedded-cluster",
expected: embeddedCluster,
},
{
raw: "k0s",
expected: k0s,
},
{
raw: "kind",
expected: kind,
},
{
raw: "k3s",
expected: k3s,
},
{
raw: "ibm",
expected: ibm,
},
{
raw: "ibmcloud",
expected: ibm,
},
{
raw: "ibm cloud",
expected: ibm,
},
{
raw: "gke",
expected: gke,
},
{
raw: "aks",
expected: aks,
},
{
raw: "eks",
expected: eks,
},
{
raw: "oke",
expected: oke,
},
{
raw: "rke2",
expected: rke2,
},
{
raw: "dockerdesktop",
expected: dockerDesktop,
},
{
raw: "docker desktop",
expected: dockerDesktop,
},
{
raw: "docker-desktop",
expected: dockerDesktop,
},
}
for _, test := range tests {
@@ -83,3 +169,48 @@ func Test_mustNormalizeDistributionName(t *testing.T) {
})
}
}
func TestParseNodesForProviders(t *testing.T) {
tests := []struct {
name string
nodes []corev1.Node
wantProviders providers
wantProviderString string
}{
{
name: "embedded-cluster",
nodes: []corev1.Node{
{
ObjectMeta: metav1.ObjectMeta{
Name: "embedded-cluster",
Labels: map[string]string{
"beta.kubernetes.io/arch": "amd64",
"beta.kubernetes.io/os": "linux",
"kots.io/embedded-cluster-role": "total-1",
"kots.io/embedded-cluster-role-0": "management",
"kubernetes.io/arch": "amd64",
"kubernetes.io/hostname": "evans-vm1",
"kubernetes.io/os": "linux",
"management": "true",
"node-role.kubernetes.io/control-plane": "true",
"node.k0sproject.io/role": "control-plane",
},
},
},
},
wantProviders: providers{embeddedCluster: true, k0s: true},
wantProviderString: "embedded-cluster",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
providers, stringProvider := ParseNodesForProviders(tt.nodes)
assert.Equalf(t, tt.wantProviders, providers,
"ParseNodesForProviders() gotProviders = %v, providers %v", providers, tt.wantProviders,
)
assert.Equalf(t, tt.wantProviderString, stringProvider,
"ParseNodesForProviders() gotStringProvider = %v, stringProvider %v", stringProvider, tt.wantProviderString,
)
})
}
}
+218
View File
@@ -0,0 +1,218 @@
package analyzer
import (
"bytes"
"encoding/json"
"fmt"
"path"
"regexp"
"strconv"
"strings"
"text/template"
"github.com/pkg/errors"
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
"github.com/replicatedhq/troubleshoot/pkg/constants"
corev1 "k8s.io/api/core/v1"
"k8s.io/klog/v2"
)
type AnalyzeEvent struct {
analyzer *troubleshootv1beta2.EventAnalyze
}
type eventFilter struct {
kind string
reason string
msgRegex string
}
func (a *AnalyzeEvent) Title() string {
if a.analyzer.CheckName != "" {
return a.analyzer.CheckName
}
if a.analyzer.CollectorName != "" {
return a.analyzer.CollectorName
}
return "Event"
}
func (a *AnalyzeEvent) IsExcluded() (bool, error) {
return isExcluded(a.analyzer.Exclude)
}
func (a *AnalyzeEvent) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) {
// required check
if a.analyzer.Reason == "" {
return nil, errors.New("reason is required")
}
// read collected events based on namespace
namespace := getNamespace(a.analyzer.Namespace)
fullPath := path.Join(constants.CLUSTER_RESOURCES_DIR, constants.CLUSTER_RESOURCES_EVENTS, namespace)
fullPath = fmt.Sprintf("%s.json", fullPath)
fileContent, err := getFile(fullPath)
if err != nil {
return nil, errors.Wrapf(err, "failed to read collected events for namespace: %s", namespace)
}
events, err := convertToEventList(fileContent)
if err != nil {
return nil, errors.Wrap(err, "failed to read collected events")
}
// filter if there's single event matched with the given criteria
// match: Reason && Kind (optional) && MessageRegex (optional)
// e.g. Reason: Unhealthy. Kind: Pod. Message: Readiness probe failed:...
event := getEvent(events, eventFilter{
kind: a.analyzer.Kind,
reason: a.analyzer.Reason,
msgRegex: a.analyzer.RegexPattern,
})
return analyzeEventResult(event, a.analyzer.Outcomes, a.Title())
}
func getNamespace(namespace string) string {
if namespace == "" {
return corev1.NamespaceDefault
}
return namespace
}
func convertToEventList(data []byte) (*corev1.EventList, error) {
var eventList corev1.EventList
err := json.Unmarshal(data, &eventList)
if err != nil {
return nil, fmt.Errorf("failed to convert []byte to corev1.EventList: %w", err)
}
return &eventList, nil
}
func getEvent(events *corev1.EventList, filter eventFilter) *corev1.Event {
var (
re *regexp.Regexp
errParseRegex error
)
if filter.msgRegex != "" {
re, errParseRegex = regexp.Compile(filter.msgRegex)
if errParseRegex != nil {
klog.V(2).Infof("failed to read message regex: %v", errParseRegex)
return nil
}
}
for _, event := range events.Items {
if !matchReason(event.Reason, filter.reason) {
continue
}
if !matchKind(event.InvolvedObject.Kind, filter.kind) {
continue
}
if re == nil || re.MatchString(event.Message) {
klog.V(2).Infof("event matched: %v for reason: %s kind: %s messageRegex: %s ", event, filter.reason, filter.kind, filter.msgRegex)
return &event
}
}
return nil
}
func matchReason(actual, expected string) bool {
// not possible to have empty reason
if expected == "" {
return false
}
return strings.EqualFold(actual, expected)
}
func matchKind(actual, expected string) bool {
// kind is optional
if expected == "" {
return true
}
return strings.EqualFold(actual, expected)
}
func analyzeEventResult(event *corev1.Event, outcomes []*troubleshootv1beta2.Outcome, checkName string) ([]*AnalyzeResult, error) {
results := []*AnalyzeResult{}
// for now, only support single outcome
// we will return when there's a matched event
willReturn := event != nil
result := &AnalyzeResult{
Title: checkName,
IconKey: "kubernetes_event",
IconURI: "https://troubleshoot.sh/images/analyzer-icons/kubernetes.svg?w=16&h=16",
}
for _, o := range outcomes {
if o.Fail != nil {
toReturn, err := strconv.ParseBool(o.Fail.When)
if err != nil {
return nil, errors.Wrapf(err, "failed to parse when condition: %s", o.Fail.When)
}
if toReturn == willReturn {
result.IsFail = true
result.Message = decorateMessage(o.Fail.Message, event)
result.URI = o.Fail.URI
break
}
}
if o.Warn != nil {
toReturn, err := strconv.ParseBool(o.Warn.When)
if err != nil {
return nil, errors.Wrapf(err, "failed to parse when condition: %s", o.Warn.When)
}
if toReturn == willReturn {
result.IsWarn = true
result.Message = decorateMessage(o.Warn.Message, event)
result.URI = o.Warn.URI
break
}
}
if o.Pass != nil {
toReturn, err := strconv.ParseBool(o.Pass.When)
if err != nil {
return nil, errors.Wrapf(err, "failed to parse when condition: %s", o.Pass.When)
}
if toReturn == willReturn {
result.IsPass = true
result.Message = decorateMessage(o.Pass.Message, event)
result.URI = o.Pass.URI
break
}
}
}
results = append(results, result)
return results, nil
}
func decorateMessage(message string, event *corev1.Event) string {
if event == nil {
return message
}
out := fmt.Sprintf("Event matched. Reason: %s Name: %s Message: %s", event.Reason, event.InvolvedObject.Name, event.Message)
tmpl := template.New("event")
msgTmpl, err := tmpl.Parse(message)
if err != nil {
klog.V(2).Infof("failed to parse message template: %v", err)
return out
}
var m bytes.Buffer
err = msgTmpl.Execute(&m, event)
if err != nil {
klog.V(2).Infof("failed to render message template: %v", err)
return out
}
return strings.TrimSpace(m.String())
}
+310
View File
@@ -0,0 +1,310 @@
package analyzer
import (
"testing"
"github.com/pkg/errors"
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
"github.com/stretchr/testify/require"
corev1 "k8s.io/api/core/v1"
)
func TestAnalyzeEvent(t *testing.T) {
tests := []struct {
name string
analyzer troubleshootv1beta2.EventAnalyze
expectResult []AnalyzeResult
files map[string][]byte
err error
}{
{
name: "reason is required",
analyzer: troubleshootv1beta2.EventAnalyze{
CollectorName: "event-collector-0",
Kind: "Pod",
Namespace: "default",
Outcomes: []*troubleshootv1beta2.Outcome{
{
Fail: &troubleshootv1beta2.SingleOutcome{
When: "true",
Message: "test",
},
},
},
},
err: errors.New("reason is required"),
files: map[string][]byte{
"cluster-resources/events/default.json": []byte(`
{
"kind": "EventList",
"apiVersion": "v1",
"metadata": {
"resourceVersion": "722"
},
"items": [
{
"kind": "Event",
"apiVersion": "v1",
"metadata": {
"name": "nginx-rc",
"namespace": "default",
"creationTimestamp": "2022-01-01T00:00:00Z"
},
"involvedObject": {
"kind": "Pod",
"name": "nginx-rc-12345",
"namespace": "default"
},
"reason": "OOMKilled",
"message": "The container was killed due to an out-of-memory condition.",
"type": "Warning"
}
]
}
`),
},
},
{
name: "fail when OOMKilled event is present",
analyzer: troubleshootv1beta2.EventAnalyze{
CollectorName: "event-collector-1",
Kind: "Pod",
Namespace: "default",
Reason: "OOMKilled",
Outcomes: []*troubleshootv1beta2.Outcome{
{
Fail: &troubleshootv1beta2.SingleOutcome{
When: "true",
Message: "Detect OOMKilled event with {{ .InvolvedObject.Kind }}-{{ .InvolvedObject.Name }} with message {{ .Message }}",
},
Pass: &troubleshootv1beta2.SingleOutcome{
When: "false",
Message: "No OOMKilled event detected",
},
},
},
},
expectResult: []AnalyzeResult{
{
Title: "event-collector-1",
IconKey: "kubernetes_event",
IconURI: "https://troubleshoot.sh/images/analyzer-icons/kubernetes.svg?w=16&h=16",
IsFail: true,
IsWarn: false,
IsPass: false,
Message: "Detect OOMKilled event with Pod-nginx-rc-12345 with message The container was killed due to an out-of-memory condition.",
},
},
files: map[string][]byte{
"cluster-resources/events/default.json": []byte(`
{
"kind": "EventList",
"apiVersion": "v1",
"metadata": {
"resourceVersion": "722"
},
"items": [
{
"kind": "Event",
"apiVersion": "v1",
"metadata": {
"name": "nginx-rc",
"namespace": "default",
"creationTimestamp": "2022-01-01T00:00:00Z"
},
"involvedObject": {
"kind": "Pod",
"name": "nginx-rc-12345",
"namespace": "default"
},
"reason": "OOMKilled",
"message": "The container was killed due to an out-of-memory condition.",
"type": "Warning"
}
]
}
`),
},
},
{
name: "pass when no FailedMount event is present",
analyzer: troubleshootv1beta2.EventAnalyze{
CollectorName: "event-collector-2",
Kind: "Pod",
Namespace: "default",
Reason: "FailedMount",
Outcomes: []*troubleshootv1beta2.Outcome{
{
Pass: &troubleshootv1beta2.SingleOutcome{
When: "false",
Message: "No FailedMount event detected",
},
},
},
},
expectResult: []AnalyzeResult{
{
Title: "event-collector-2",
IconKey: "kubernetes_event",
IconURI: "https://troubleshoot.sh/images/analyzer-icons/kubernetes.svg?w=16&h=16",
IsFail: false,
IsWarn: false,
IsPass: true,
Message: "No FailedMount event detected",
},
},
files: map[string][]byte{
"cluster-resources/events/default.json": []byte(`
{
"kind": "EventList",
"apiVersion": "v1",
"metadata": {
"resourceVersion": "722"
},
"items": [
{
"kind": "Event",
"apiVersion": "v1",
"metadata": {
"name": "nginx-rc-1",
"namespace": "default",
"creationTimestamp": "2022-01-01T00:00:00Z"
},
"involvedObject": {
"kind": "Pod",
"name": "nginx-rc-12345",
"namespace": "default"
},
"reason": "Created",
"message": "Created container",
"type": "Normal"
},
{
"kind": "Event",
"apiVersion": "v1",
"metadata": {
"name": "nginx-rc-2",
"namespace": "default",
"creationTimestamp": "2022-01-01T00:00:00Z"
},
"involvedObject": {
"kind": "Pod",
"name": "nginx-rc-67890",
"namespace": "default"
},
"reason": "Started",
"message": "Started container",
"type": "Normal"
}
]
}
`),
},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
req := require.New(t)
getFile := func(n string) ([]byte, error) {
if b, ok := test.files[n]; ok {
return b, nil
}
return nil, errors.New("file not found")
}
findFiles := func(n string, _ []string) (map[string][]byte, error) {
return nil, errors.New("method not implemented")
}
a := &AnalyzeEvent{
analyzer: &test.analyzer,
}
actual, err := a.Analyze(getFile, findFiles)
if test.err != nil {
req.EqualError(err, test.err.Error())
return
}
req.NoError(err)
unPointered := []AnalyzeResult{}
for _, v := range actual {
unPointered = append(unPointered, *v)
}
req.ElementsMatch(test.expectResult, unPointered)
})
}
}
func TestAnalyzeEventResult(t *testing.T) {
event := &corev1.Event{
InvolvedObject: corev1.ObjectReference{
Kind: "Pod",
Name: "foo-pod",
},
Reason: "Unhealthy",
Message: "foo-message",
Type: "Warning",
}
outcomes := []*troubleshootv1beta2.Outcome{
{
Fail: &troubleshootv1beta2.SingleOutcome{
When: "true",
Message: "No unhealthy pods allowed",
},
Pass: &troubleshootv1beta2.SingleOutcome{
When: "false",
Message: "No unhealthy pod detected",
},
},
}
checkName := "Test Event"
expectedResults := []*AnalyzeResult{
{
Title: "Test Event",
IconKey: "kubernetes_event",
IconURI: "https://troubleshoot.sh/images/analyzer-icons/kubernetes.svg?w=16&h=16",
IsFail: true,
IsWarn: false,
IsPass: false,
Message: "No unhealthy pods allowed",
},
}
results, err := analyzeEventResult(event, outcomes, checkName)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if len(results) != len(expectedResults) {
t.Fatalf("unexpected number of results, got %d, want %d", len(results), len(expectedResults))
}
for i, result := range results {
expectedResult := expectedResults[i]
if result.Title != expectedResult.Title {
t.Errorf("unexpected title, got %s, want %s", result.Title, expectedResult.Title)
}
if result.IsFail != expectedResult.IsFail {
t.Errorf("unexpected IsFail value, got %v, want %v", result.IsFail, expectedResult.IsFail)
}
if result.IsWarn != expectedResult.IsWarn {
t.Errorf("unexpected IsWarn value, got %v, want %v", result.IsWarn, expectedResult.IsWarn)
}
if result.IsPass != expectedResult.IsPass {
t.Errorf("unexpected IsPass value, got %v, want %v", result.IsPass, expectedResult.IsPass)
}
if result.Message != expectedResult.Message {
t.Errorf("unexpected message, got %s, want %s", result.Message, expectedResult.Message)
}
}
}
@@ -0,0 +1,47 @@
{
"kind": "ConfigMapList",
"apiVersion": "v1",
"metadata": {
"resourceVersion": "4825753"
},
"items": [
{
"kind": "ConfigMap",
"apiVersion": "v1",
"metadata": {
"name": "kube-root-ca.crt",
"namespace": "kube-public",
"uid": "37a912b2-a666-480f-a1a8-05ab012432e4",
"resourceVersion": "332",
"creationTimestamp": "2023-05-29T23:33:07Z",
"annotations": {
"kubernetes.io/description": "Contains a CA bundle that can be used to verify the kube-apiserver when using internal endpoints such as the internal service IP or kubernetes.default.svc. No other usage is guaranteed across distributions of Kubernetes clusters."
},
"managedFields": [
{
"manager": "kube-controller-manager",
"operation": "Update",
"apiVersion": "v1",
"time": "2023-05-29T23:33:07Z",
"fieldsType": "FieldsV1",
"fieldsV1": {
"f:data": {
".": {},
"f:ca.crt": {}
},
"f:metadata": {
"f:annotations": {
".": {},
"f:kubernetes.io/description": {}
}
}
}
}
]
},
"data": {
"ca.crt": "-----BEGIN CERTIFICATE-----\nMIIDBjCCAe6gAwIBAgIBATANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDEwptaW5p\na3ViZUNBMB4XDTIzMDUyODIzMzIzOVoXDTMzMDUyNjIzMzIzOVowFTETMBEGA1UE\nAxMKbWluaWt1YmVDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOpU\nswd15tD+QCelgYlu5MRB260+Ke63gEDTkXIyAr+mR+TjW/v9TPPIP9iidvTUg+jq\nryrf1PwURVx3EUSZWtd9NpAEDT1ov/ggx16xxj2El7KLen0SXQutSF28zjCFXxYG\nMkPxXu+qYsn2mLJX5i1kaCZNffyToCJ0n2bxxx83rOS+fgz11JntAwcgC8V3Mtq6\nIv+2Xb9PSxPs38ef7r15j5KSTOrmWCR5texPFz/WU/YbZ3W42pj9T/EiuGwamfmI\ngevuwv7AxlfjKutp5UQEth5GhY6V4kJyVIUExN3ddEsTPLQD9zvdsP4DlkGpZmiR\n/Ip3rXY/ldxeeGZ0HUUCAwEAAaNhMF8wDgYDVR0PAQH/BAQDAgKkMB0GA1UdJQQW\nMBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW\nBBS0XUXhCu/DOH8/0W5L0n4BOw9b6zANBgkqhkiG9w0BAQsFAAOCAQEAHrXOxKdy\n+DvPtvgfzzV3qqmIvTuuFyW0BdZdXV8yo1tZajkEO0B0HvLUyn8ljKgoK5YtCQcr\nzSj6QEewgP+JCBTsWCKzbOhMcDKw1pa6bSeLcQWwMxox+1Zcj7edMPlPcQ3SVLxZ\n6y7fD7BArTKRBKCr8Uwudwox5Vm0URWLRAvb+8jPv9BDuC/uMPJ4UrexL/Q2QQs8\nQkyWYeSk4mBCM3qAahQhYc0WSHbk+a/5iua/y+VUaa208CUbm5glBoAroHDk5eTN\nYstOSLUQAlzTdr4kCEVi+a3+NgmuvzYXWubAdy/PT860aFBJlmVNuDhy8V/bGpnS\nKxmG7B3yJmbmzg==\n-----END CERTIFICATE-----\n"
}
}
]
}
+135
View File
@@ -0,0 +1,135 @@
package analyzer
import (
"encoding/json"
"fmt"
"github.com/pkg/errors"
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
"github.com/replicatedhq/troubleshoot/pkg/constants"
)
type AnalyzeGoldpinger struct {
analyzer *troubleshootv1beta2.GoldpingerAnalyze
}
type checkAllOutput struct {
Hosts []struct {
HostIP string `json:"hostIP"`
PodIP string `json:"podIP"`
PodName string `json:"podName"`
} `json:"hosts"`
Responses map[string]struct {
HostIP string `json:"hostIP"`
PodIP string `json:"podIP"`
OK bool `json:"OK"`
Response struct {
PodResults map[string]struct {
HostIP string `json:"hostIP"`
OK bool `json:"OK"`
PingTime string `json:"pingTime"`
PodIP string `json:"podIP"`
Response struct {
BootTime string `json:"boot_time"`
} `json:"response"`
Error string `json:"error"`
ResponseTimeMS int `json:"response-time-ms"`
StatusCode int `json:"status-code"`
} `json:"podResults"`
} `json:"response"`
} `json:"responses"`
}
func (a *AnalyzeGoldpinger) Title() string {
title := a.analyzer.CheckName
if title == "" {
title = a.collectorName()
}
return title
}
func (a *AnalyzeGoldpinger) IsExcluded() (bool, error) {
return isExcluded(a.analyzer.Exclude)
}
func (a *AnalyzeGoldpinger) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) {
caoFilePath := constants.GP_CHECK_ALL_RESULTS_PATH
// To allow analysing older support bundles, we can provide a custom file path
if a.analyzer.FilePath != "" {
caoFilePath = a.analyzer.FilePath
}
collected, err := getFile(caoFilePath)
if err != nil {
return nil, errors.Wrapf(err, "failed to read collected file path: %q", caoFilePath)
}
var cao checkAllOutput
err = json.Unmarshal(collected, &cao)
if err != nil {
return nil, errors.Wrap(err, "failed to unmarshal collected goldpinger output")
}
return a.podPingsAnalysis(&cao), nil
}
func (a *AnalyzeGoldpinger) collectorName() string {
if a.analyzer.CollectorName != "" {
return a.analyzer.CollectorName
}
return "goldpinger"
}
func (a *AnalyzeGoldpinger) podPingsAnalysis(cao *checkAllOutput) []*AnalyzeResult {
results := []*AnalyzeResult{}
for _, host := range cao.Hosts {
// Check if the pod from a host has any ping errors from other pods
targetPod := host.PodName
pingsSucceeded := true
for srcPod, resp := range cao.Responses {
res := &AnalyzeResult{
IconKey: "kubernetes",
Strict: a.analyzer.Strict.BoolOrDefaultFalse(),
}
// Get ping result for the pod
podResult, ok := resp.Response.PodResults[targetPod]
if !ok {
// Pod not found in ping results from the source pod
res.IsWarn = true
res.Title = fmt.Sprintf("Missing ping results for %q pod", targetPod)
res.Message = fmt.Sprintf("Ping result for %q pod from %q pod is missing", targetPod, srcPod)
pingsSucceeded = false
results = append(results, res)
continue
}
if !podResult.OK {
// Ping was not successful
res.IsFail = true
res.Title = fmt.Sprintf("Ping from %q pod to %q pod failed", srcPod, targetPod)
res.Message = fmt.Sprintf("Ping error: %s", podResult.Error)
pingsSucceeded = false
results = append(results, res)
continue
}
}
// If all pings succeeded, add a pass result
if pingsSucceeded {
results = append(results, &AnalyzeResult{
IconKey: "kubernetes",
Strict: a.analyzer.Strict.BoolOrDefaultFalse(),
IsPass: true,
Title: fmt.Sprintf("Pings to %q pod succeeded", targetPod),
Message: fmt.Sprintf("Pings to %q pod from all other pods in the cluster succeeded", targetPod),
})
}
}
return results
}
+125
View File
@@ -0,0 +1,125 @@
package analyzer
import (
"encoding/json"
"testing"
"github.com/replicatedhq/troubleshoot/internal/testutils"
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestUnmarshallingCheckAllResults(t *testing.T) {
s := testutils.GetTestFixture(t, "goldpinger/checkall-with-error.json")
var res checkAllOutput
err := json.Unmarshal([]byte(s), &res)
require.NoError(t, err)
assert.Len(t, res.Hosts, 3)
assert.Equal(t, "goldpinger-tbdsb", res.Hosts[1].PodName)
assert.Equal(t, "10.32.2.2", res.Responses["goldpinger-4hctt"].Response.PodResults["goldpinger-jj9mw"].PodIP)
assert.Equal(t,
`Get "http://10.32.0.9:80/ping": context deadline exceeded`,
res.Responses["goldpinger-tbdsb"].Response.PodResults["goldpinger-4hctt"].Error,
)
}
func TestAnalyzeGoldpinger_podPingsAnalysis(t *testing.T) {
tests := []struct {
name string
cao *checkAllOutput
want []*AnalyzeResult
}{
{
name: "no ping errors",
cao: caoFixture(t, "goldpinger/checkall-success.json"),
want: []*AnalyzeResult{
{
Title: "Pings to \"goldpinger-kpz4g\" pod succeeded",
Message: "Pings to \"goldpinger-kpz4g\" pod from all other pods in the cluster succeeded",
IconKey: "kubernetes",
IsPass: true,
},
{
Title: "Pings to \"goldpinger-k6d2j\" pod succeeded",
Message: "Pings to \"goldpinger-k6d2j\" pod from all other pods in the cluster succeeded",
IconKey: "kubernetes",
IsPass: true,
},
{
Title: "Pings to \"goldpinger-5ck4d\" pod succeeded",
Message: "Pings to \"goldpinger-5ck4d\" pod from all other pods in the cluster succeeded",
IconKey: "kubernetes",
IsPass: true,
},
},
},
{
name: "with some ping errors",
cao: caoFixture(t, "goldpinger/checkall-with-error.json"),
want: []*AnalyzeResult{
{
Title: "Ping from \"goldpinger-jj9mw\" pod to \"goldpinger-4hctt\" pod failed",
Message: "Ping error: Get \"http://10.32.0.9:80/ping\": context deadline exceeded",
IconKey: "kubernetes",
IsFail: true,
},
{
Title: "Ping from \"goldpinger-jj9mw\" pod to \"goldpinger-tbdsb\" pod failed",
Message: "Ping error: Get \"http://10.32.1.2:80/ping\": context deadline exceeded",
IconKey: "kubernetes",
IsFail: true,
},
{
Title: "Ping from \"goldpinger-4hctt\" pod to \"goldpinger-jj9mw\" pod failed",
Message: "Ping error: Get \"http://10.32.2.2:80/ping\": context deadline exceeded",
IconKey: "kubernetes",
IsFail: true,
},
{
Title: "Ping from \"goldpinger-4hctt\" pod to \"goldpinger-tbdsb\" pod failed",
Message: "Ping error: Get \"http://10.32.1.2:80/ping\": context deadline exceeded",
IconKey: "kubernetes",
IsFail: true,
},
{
Title: "Ping from \"goldpinger-tbdsb\" pod to \"goldpinger-4hctt\" pod failed",
Message: "Ping error: Get \"http://10.32.0.9:80/ping\": context deadline exceeded",
IconKey: "kubernetes",
IsFail: true,
},
{
Title: "Ping from \"goldpinger-tbdsb\" pod to \"goldpinger-jj9mw\" pod failed",
Message: "Ping error: Get \"http://10.32.2.2:80/ping\": context deadline exceeded",
IconKey: "kubernetes",
IsFail: true,
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
a := &AnalyzeGoldpinger{
analyzer: &troubleshootv1beta2.GoldpingerAnalyze{},
}
got := a.podPingsAnalysis(tt.cao)
// Check existence of each want. Maps are not ordered, so we can't just compare
for _, want := range tt.want {
assert.Contains(t, got, want)
}
assert.Len(t, got, len(tt.want))
})
}
}
func caoFixture(t *testing.T, path string) *checkAllOutput {
t.Helper()
s := testutils.GetTestFixture(t, path)
var res checkAllOutput
err := json.Unmarshal([]byte(s), &res)
require.NoError(t, err)
return &res
}
+4
View File
@@ -52,6 +52,10 @@ func GetHostAnalyzer(analyzer *troubleshootv1beta2.HostAnalyze) (HostAnalyzer, b
return &AnalyzeHostOS{analyzer.HostOS}, true
case analyzer.TextAnalyze != nil:
return &AnalyzeHostTextAnalyze{analyzer.TextAnalyze}, true
case analyzer.KernelConfigs != nil:
return &AnalyzeHostKernelConfigs{analyzer.KernelConfigs}, true
case analyzer.JsonCompare != nil:
return &AnalyzeHostJsonCompare{analyzer.JsonCompare}, true
default:
return nil, false
}
+37 -32
View File
@@ -38,7 +38,41 @@ func (a *AnalyzeHostHTTP) Analyze(
if hostAnalyzer.CollectorName != "" {
name = filepath.Join("host-collectors/http", hostAnalyzer.CollectorName+".json")
}
contents, err := getCollectedFileContents(name)
return analyzeHTTPResult(hostAnalyzer, name, getCollectedFileContents, a.Title())
}
func compareHostHTTPConditionalToActual(conditional string, result *httpResult) (res bool, err error) {
if conditional == "error" {
return result.Error != nil, nil
}
parts := strings.Split(conditional, " ")
if len(parts) != 3 {
return false, fmt.Errorf("Failed to parse conditional: got %d parts", len(parts))
}
if parts[0] != "statusCode" {
return false, errors.New(`Conditional must begin with keyword "statusCode"`)
}
if parts[1] != "=" && parts[1] != "==" && parts[1] != "===" {
return false, errors.New(`Only supported operator is "=="`)
}
i, err := strconv.Atoi(parts[2])
if err != nil {
return false, err
}
if result.Response == nil {
return false, err
}
return result.Response.Status == i, nil
}
func analyzeHTTPResult(analyzer *troubleshootv1beta2.HTTPAnalyze, fileName string, getCollectedFileContents getCollectedFileContents, title string) ([]*AnalyzeResult, error) {
contents, err := getCollectedFileContents(fileName)
if err != nil {
return nil, errors.Wrap(err, "failed to get collected file")
}
@@ -49,10 +83,10 @@ func (a *AnalyzeHostHTTP) Analyze(
}
result := &AnalyzeResult{
Title: a.Title(),
Title: title,
}
for _, outcome := range hostAnalyzer.Outcomes {
for _, outcome := range analyzer.Outcomes {
if outcome.Fail != nil {
if outcome.Fail.When == "" {
result.IsFail = true
@@ -122,32 +156,3 @@ func (a *AnalyzeHostHTTP) Analyze(
return []*AnalyzeResult{result}, nil
}
func compareHostHTTPConditionalToActual(conditional string, result *httpResult) (res bool, err error) {
if conditional == "error" {
return result.Error != nil, nil
}
parts := strings.Split(conditional, " ")
if len(parts) != 3 {
return false, fmt.Errorf("Failed to parse conditional: got %d parts", len(parts))
}
if parts[0] != "statusCode" {
return false, errors.New(`Conditional must begin with keyword "statusCode"`)
}
if parts[1] != "=" && parts[1] != "==" && parts[1] != "===" {
return false, errors.New(`Only supported operator is "=="`)
}
i, err := strconv.Atoi(parts[2])
if err != nil {
return false, err
}
if result.Response == nil {
return false, err
}
return result.Response.Status == i, nil
}
+28
View File
@@ -0,0 +1,28 @@
package analyzer
import (
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
)
type AnalyzeHostJsonCompare struct {
hostAnalyzer *troubleshootv1beta2.JsonCompare
}
func (a *AnalyzeHostJsonCompare) Title() string {
return jsonCompareTitle(a.hostAnalyzer)
}
func (a *AnalyzeHostJsonCompare) IsExcluded() (bool, error) {
return isExcluded(a.hostAnalyzer.Exclude)
}
func (a *AnalyzeHostJsonCompare) Analyze(
getCollectedFileContents func(string) ([]byte, error), findFiles getChildCollectedFileContents,
) ([]*AnalyzeResult, error) {
result, err := analyzeJsonCompare(a.hostAnalyzer, getCollectedFileContents, a.Title())
if err != nil {
return nil, err
}
result.Strict = a.hostAnalyzer.Strict.BoolOrDefaultFalse()
return []*AnalyzeResult{result}, nil
}
+97
View File
@@ -0,0 +1,97 @@
package analyzer
import (
"encoding/json"
"regexp"
"strings"
"github.com/pkg/errors"
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
"github.com/replicatedhq/troubleshoot/pkg/collect"
"k8s.io/klog/v2"
)
type AnalyzeHostKernelConfigs struct {
hostAnalyzer *troubleshootv1beta2.KernelConfigsAnalyze
}
func (a *AnalyzeHostKernelConfigs) Title() string {
return hostAnalyzerTitleOrDefault(a.hostAnalyzer.AnalyzeMeta, "Kernel Configs")
}
func (a *AnalyzeHostKernelConfigs) IsExcluded() (bool, error) {
return isExcluded(a.hostAnalyzer.Exclude)
}
func (a *AnalyzeHostKernelConfigs) Analyze(
getCollectedFileContents func(string) ([]byte, error), findFiles getChildCollectedFileContents,
) ([]*AnalyzeResult, error) {
hostAnalyzer := a.hostAnalyzer
contents, err := getCollectedFileContents(collect.HostKernelConfigsPath)
if err != nil {
return nil, errors.Wrap(err, "failed to get collected file")
}
kConfigs := collect.KConfigs{}
if err := json.Unmarshal(contents, &kConfigs); err != nil {
return nil, errors.Wrap(err, "failed to read kernel configs")
}
var configsNotFound []string
kConfigRegex := regexp.MustCompile("^(CONFIG_[A-Z0-9_]+)=([ymn]+)$")
for _, config := range hostAnalyzer.SelectedConfigs {
matches := kConfigRegex.FindStringSubmatch(config)
// zero tolerance for invalid kernel config
if matches == nil || len(matches) < 3 {
return nil, errors.Errorf("invalid kernel config: %s", config)
}
key := matches[1]
values := matches[2] // values can contain multiple values in any order y, m, n
// check if the kernel config exists
if _, ok := kConfigs[key]; !ok {
configsNotFound = append(configsNotFound, config)
continue
}
// check if the kernel config value matches
if !strings.Contains(values, kConfigs[key]) {
klog.V(2).Infof("collected kernel config %s=%s does not in expected values %s", key, kConfigs[key], values)
configsNotFound = append(configsNotFound, config)
}
}
var results []*AnalyzeResult
for _, outcome := range hostAnalyzer.Outcomes {
result := &AnalyzeResult{
Title: a.Title(),
Strict: hostAnalyzer.Strict.BoolOrDefaultFalse(),
}
if outcome.Pass != nil && len(configsNotFound) == 0 {
result.IsPass = true
result.Message = outcome.Pass.Message
results = append(results, result)
break
}
if outcome.Fail != nil && len(configsNotFound) > 0 {
result.IsFail = true
result.Message = addMissingKernelConfigs(outcome.Fail.Message, configsNotFound)
results = append(results, result)
break
}
}
return results, nil
}
func addMissingKernelConfigs(message string, missingConfigs []string) string {
if message == "" && len(missingConfigs) == 0 {
return message
}
return strings.ReplaceAll(message, "{{ .ConfigsNotFound }}", strings.Join(missingConfigs, ", "))
}
+129
View File
@@ -0,0 +1,129 @@
package analyzer
import (
"testing"
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
"github.com/stretchr/testify/assert"
)
func TestAnalyzeKernelConfigs(t *testing.T) {
tests := []struct {
name string
selectedConfigs []string
outcomes []*troubleshootv1beta2.Outcome
results []*AnalyzeResult
expectErr bool
}{
{
name: "all pass",
selectedConfigs: []string{"CONFIG_CGROUP_FREEZER=y", "CONFIG_NETFILTER_XTABLES=m"},
outcomes: []*troubleshootv1beta2.Outcome{
{
Pass: &troubleshootv1beta2.SingleOutcome{
Message: "required kernel configs are available",
},
},
},
results: []*AnalyzeResult{
{
Title: "Kernel Configs",
IsPass: true,
Message: "required kernel configs are available",
},
},
expectErr: false,
},
{
name: "has fail",
selectedConfigs: []string{"CONFIG_UTS_NS=y"},
outcomes: []*troubleshootv1beta2.Outcome{
{
Fail: &troubleshootv1beta2.SingleOutcome{
Message: "missing kernel config(s): {{ .ConfigsNotFound }}",
},
},
},
results: []*AnalyzeResult{
{
Title: "Kernel Configs",
IsFail: true,
Message: "missing kernel config(s): CONFIG_UTS_NS=y",
},
},
expectErr: false,
},
{
name: "kernel config disabled",
selectedConfigs: []string{"CONFIG_CGROUP_FREEZER=n"},
outcomes: []*troubleshootv1beta2.Outcome{
{
Fail: &troubleshootv1beta2.SingleOutcome{
Message: "missing kernel config(s): {{ .ConfigsNotFound }}",
},
},
},
results: []*AnalyzeResult{
{
Title: "Kernel Configs",
IsFail: true,
Message: "missing kernel config(s): CONFIG_CGROUP_FREEZER=n",
},
},
expectErr: false,
},
{
name: "invalid kernel config",
selectedConfigs: []string{"foobar=n"},
expectErr: true,
},
{
name: "select multiple kernel config values",
selectedConfigs: []string{"CONFIG_BRIDGE=my"},
outcomes: []*troubleshootv1beta2.Outcome{
{
Pass: &troubleshootv1beta2.SingleOutcome{
Message: "required kernel configs are available",
},
},
},
results: []*AnalyzeResult{
{
Title: "Kernel Configs",
IsPass: true,
Message: "required kernel configs are available",
},
},
expectErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
mockKernelFile := func(_ string) ([]byte, error) {
return []byte(`{"CONFIG_CGROUP_FREEZER": "y", "CONFIG_NETFILTER_XTABLES": "m", "CONFIG_BRIDGE": "y"}`), nil
}
analyzer := AnalyzeHostKernelConfigs{
hostAnalyzer: &troubleshootv1beta2.KernelConfigsAnalyze{
AnalyzeMeta: troubleshootv1beta2.AnalyzeMeta{
CheckName: "Kernel Configs",
},
SelectedConfigs: tt.selectedConfigs,
Outcomes: tt.outcomes,
},
}
results, err := analyzer.Analyze(mockKernelFile, nil)
if tt.expectErr {
assert.Error(t, err)
} else {
assert.NoError(t, err)
assert.Equal(t, tt.results, results)
}
})
}
}
+23 -4
View File
@@ -86,19 +86,36 @@ func analyzeOSVersionResult(osInfo collect.HostOSInfo, outcomes []*troubleshootv
}
parts := strings.Split(when, " ")
platform := parts[0]
if len(parts) < 3 {
return []*AnalyzeResult{&result}, errors.New("when condition must have at least 3 parts")
}
expectedVer := fixVersion(parts[2])
toleratedVer, err := semver.ParseTolerant(expectedVer)
if err != nil {
return []*AnalyzeResult{&result}, errors.Wrapf(err, "failed to parse tolerant: %s", expectedVer)
return []*AnalyzeResult{&result}, errors.Wrapf(err, "failed to parse version: %s", expectedVer)
}
when = fmt.Sprintf("%s %v", parts[1], toleratedVer)
whenRange, err := semver.ParseRange(when)
if err != nil {
return []*AnalyzeResult{&result}, errors.Wrapf(err, "failed to parse range: %s", when)
return []*AnalyzeResult{&result}, errors.Wrapf(err, "failed to parse version range: %s", when)
}
// Match the kernel version regardless of the platform
// e.g "kernelVersion == 4.15"
if parts[0] == "kernelVersion" {
fixedKernelVer := fixVersion(osInfo.KernelVersion)
toleratedKernelVer, err := semver.ParseTolerant(fixedKernelVer)
if err != nil {
return []*AnalyzeResult{}, errors.Wrapf(err, "failed to parse tolerant: %v", fixedKernelVer)
}
if whenRange(toleratedKernelVer) {
return []*AnalyzeResult{&result}, nil
}
}
// Match the platform version and and kernel version passed in as
// "<platform>-<kernelVersion>-kernel" e.g "centos-8.2-kernel == 8.2"
platform := parts[0]
kernelInfo := fmt.Sprintf("%s-%s-kernel", osInfo.Platform, osInfo.PlatformVersion)
if len(strings.Split(platform, "-")) == 3 && strings.Split(platform, "-")[2] == "kernel" {
if platform == kernelInfo {
@@ -111,6 +128,8 @@ func analyzeOSVersionResult(osInfo collect.HostOSInfo, outcomes []*troubleshootv
return []*AnalyzeResult{&result}, nil
}
}
// Match the platform version
// e.g "centos == 8.2"
} else if platform == osInfo.Platform {
fixedDistVer := fixVersion(osInfo.PlatformVersion)
toleratedDistVer, err := semver.ParseTolerant(fixedDistVer)
+28
View File
@@ -319,6 +319,34 @@ func TestAnalyzeHostOS(t *testing.T) {
},
},
},
{
name: "test kernelVersion >= 6.4.9-abc",
hostInfo: collect.HostOSInfo{
Name: "my-host",
KernelVersion: "6.5.0-1024-gcp",
PlatformVersion: "22.04",
Platform: "ubuntu",
},
hostAnalyzer: &troubleshootv1beta2.HostOSAnalyze{
Outcomes: []*troubleshootv1beta2.Outcome{
{
Pass: &troubleshootv1beta2.SingleOutcome{
When: "kernelVersion >= 6.4.9-abc",
Message: "supported kernel version >= 6.4.9-abc",
},
},
},
},
result: []*AnalyzeResult{
{
Title: "Host OS Info",
IsPass: true,
Message: "supported kernel version >= 6.4.9-abc",
},
},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
+30
View File
@@ -0,0 +1,30 @@
package analyzer
import (
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
)
type AnalyzeHTTPAnalyze struct {
analyzer *troubleshootv1beta2.HTTPAnalyze
}
func (a *AnalyzeHTTPAnalyze) Title() string {
checkName := a.analyzer.CheckName
if checkName == "" {
checkName = a.analyzer.CollectorName
}
return checkName
}
func (a *AnalyzeHTTPAnalyze) IsExcluded() (bool, error) {
return isExcluded(a.analyzer.Exclude)
}
func (a *AnalyzeHTTPAnalyze) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) {
fileName := "result.json"
if a.analyzer.CollectorName != "" {
fileName = a.analyzer.CollectorName + ".json"
}
return analyzeHTTPResult(a.analyzer, fileName, getFile, a.Title())
}
+31 -6
View File
@@ -10,6 +10,7 @@ import (
"strconv"
"github.com/pkg/errors"
util "github.com/replicatedhq/troubleshoot/internal/util"
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
iutils "github.com/replicatedhq/troubleshoot/pkg/interfaceutils"
"k8s.io/client-go/util/jsonpath"
@@ -20,9 +21,16 @@ type AnalyzeJsonCompare struct {
}
func (a *AnalyzeJsonCompare) Title() string {
title := a.analyzer.CheckName
return jsonCompareTitle(a.analyzer)
}
func jsonCompareTitle(analyser *troubleshootv1beta2.JsonCompare) string {
title := analyser.CheckName
if title == "" {
title = a.analyzer.CollectorName
title = analyser.CollectorName
}
if title == "" {
title = "Json Compare"
}
return title
@@ -33,7 +41,7 @@ func (a *AnalyzeJsonCompare) IsExcluded() (bool, error) {
}
func (a *AnalyzeJsonCompare) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) {
result, err := a.analyzeJsonCompare(a.analyzer, getFile)
result, err := analyzeJsonCompare(a.analyzer, getFile, a.Title())
if err != nil {
return nil, err
}
@@ -41,7 +49,7 @@ func (a *AnalyzeJsonCompare) Analyze(getFile getCollectedFileContents, findFiles
return []*AnalyzeResult{result}, nil
}
func (a *AnalyzeJsonCompare) analyzeJsonCompare(analyzer *troubleshootv1beta2.JsonCompare, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) {
func analyzeJsonCompare(analyzer *troubleshootv1beta2.JsonCompare, getCollectedFileContents func(string) ([]byte, error), title string) (*AnalyzeResult, error) {
fullPath := filepath.Join(analyzer.CollectorName, analyzer.FileName)
collected, err := getCollectedFileContents(fullPath)
if err != nil {
@@ -54,6 +62,8 @@ func (a *AnalyzeJsonCompare) analyzeJsonCompare(analyzer *troubleshootv1beta2.Js
return nil, errors.Wrap(err, "failed to parse collected data as json")
}
originalActual := actual
if analyzer.Path != "" {
actual, err = iutils.GetAtPath(actual, analyzer.Path)
if err != nil {
@@ -94,7 +104,7 @@ func (a *AnalyzeJsonCompare) analyzeJsonCompare(analyzer *troubleshootv1beta2.Js
}
result := &AnalyzeResult{
Title: a.Title(),
Title: title,
IconKey: "kubernetes_text_analyze",
IconURI: "https://troubleshoot.sh/images/analyzer-icons/text-analyze.svg",
}
@@ -112,6 +122,11 @@ func (a *AnalyzeJsonCompare) analyzeJsonCompare(analyzer *troubleshootv1beta2.Js
}
}
outcome.Fail.Message, err = util.RenderTemplate(outcome.Fail.Message, originalActual)
if err != nil {
return nil, errors.Wrap(err, "failed to render template on outcome message")
}
if when == equal {
result.IsFail = true
result.Message = outcome.Fail.Message
@@ -128,6 +143,11 @@ func (a *AnalyzeJsonCompare) analyzeJsonCompare(analyzer *troubleshootv1beta2.Js
}
}
outcome.Warn.Message, err = util.RenderTemplate(outcome.Warn.Message, originalActual)
if err != nil {
return nil, errors.Wrap(err, "failed to render template on outcome message")
}
if when == equal {
result.IsWarn = true
result.Message = outcome.Warn.Message
@@ -144,6 +164,11 @@ func (a *AnalyzeJsonCompare) analyzeJsonCompare(analyzer *troubleshootv1beta2.Js
}
}
outcome.Pass.Message, err = util.RenderTemplate(outcome.Pass.Message, originalActual)
if err != nil {
return nil, errors.Wrap(err, "failed to render template on outcome message")
}
if when == equal {
result.IsPass = true
result.Message = outcome.Pass.Message
@@ -155,7 +180,7 @@ func (a *AnalyzeJsonCompare) analyzeJsonCompare(analyzer *troubleshootv1beta2.Js
}
return &AnalyzeResult{
Title: a.Title(),
Title: title,
IconKey: "kubernetes_text_analyze",
IconURI: "https://troubleshoot.sh/images/analyzer-icons/text-analyze.svg",
IsFail: true,
+43 -5
View File
@@ -756,6 +756,48 @@ func Test_jsonCompare(t *testing.T) {
]
}`),
},
{
name: "basic comparison with outcome message templated",
analyzer: troubleshootv1beta2.JsonCompare{
Outcomes: []*troubleshootv1beta2.Outcome{
{
Pass: &troubleshootv1beta2.SingleOutcome{
Message: "Status: {{ .morestuff.status }}, Info: {{ .morestuff.info }}",
When: "true",
},
},
{
Fail: &troubleshootv1beta2.SingleOutcome{
Message: "Status: {{ .morestuff.status }}, Info: {{ .morestuff.info }}",
When: "false",
},
},
},
CollectorName: "json-compare",
FileName: "json-compare.json",
Path: "morestuff.status",
Value: `"ready"`,
},
expectResult: AnalyzeResult{
IsPass: false,
IsWarn: false,
IsFail: true,
Title: "json-compare",
Message: "Status: notready, Info: morestuff is not ready",
IconKey: "kubernetes_text_analyze",
IconURI: "https://troubleshoot.sh/images/analyzer-icons/text-analyze.svg",
},
fileContents: []byte(`{
"stuff": {
"status": "ready",
"info": "this stuff is ready"
},
"morestuff": {
"status": "notready",
"info": "morestuff is not ready"
}
}`),
},
}
for _, test := range tests {
@@ -766,11 +808,7 @@ func Test_jsonCompare(t *testing.T) {
return test.fileContents, nil
}
a := AnalyzeJsonCompare{
analyzer: &test.analyzer,
}
actual, err := a.analyzeJsonCompare(&test.analyzer, getCollectedFileContents)
actual, err := analyzeJsonCompare(&test.analyzer, getCollectedFileContents, test.analyzer.CollectorName)
if !test.isError {
req.NoError(err)
req.Equal(test.expectResult, *actual)
+316
View File
@@ -0,0 +1,316 @@
package analyzer
import (
"bytes"
"encoding/json"
"fmt"
"path/filepath"
"regexp"
"strconv"
"strings"
"text/template"
"github.com/pkg/errors"
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
"k8s.io/klog/v2"
kubeletv1alpha1 "k8s.io/kubelet/pkg/apis/stats/v1alpha1"
)
type AnalyzeNodeMetrics struct {
analyzer *troubleshootv1beta2.NodeMetricsAnalyze
}
type nodeMetricsComparisonResults struct {
PVC pvcTemplateData
}
type pvcTemplateData struct {
UsedPercentage float64
ConcatenatedNames string
Names []string
}
type pvcUsageStats struct {
PvcName string
Used float64
}
func (a *AnalyzeNodeMetrics) Title() string {
title := a.analyzer.CheckName
if title == "" {
title = a.analyzer.CollectorName
}
if title == "" {
title = "Node Metrics"
}
return title
}
func (a *AnalyzeNodeMetrics) IsExcluded() (bool, error) {
return isExcluded(a.analyzer.Exclude)
}
func (a *AnalyzeNodeMetrics) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) {
// Gather all collected node-metrics files
collected, err := findFiles(filepath.Join("node-metrics", "*.json"), nil)
if err != nil {
return nil, errors.Wrap(err, "failed to read collected pods")
}
// Unmarshal all collected node-metrics files
summaries := []kubeletv1alpha1.Summary{}
for _, fileContent := range collected {
summary := kubeletv1alpha1.Summary{}
if err := json.Unmarshal(fileContent, &summary); err != nil {
return nil, errors.Wrap(err, "failed to unmarshal node metrics")
}
summaries = append(summaries, summary)
}
// Run through all outcomes to generate results
result, err := a.compareCollectedMetricsWithOutcomes(summaries)
if err != nil {
return nil, errors.Wrap(err, "failed to compare node metrics with outcomes")
}
if result == nil {
return []*AnalyzeResult{}, nil
}
result.Strict = a.analyzer.Strict.BoolOrDefaultFalse()
return []*AnalyzeResult{result}, nil
}
func (a *AnalyzeNodeMetrics) compareCollectedMetricsWithOutcomes(summaries []kubeletv1alpha1.Summary) (*AnalyzeResult, error) {
for _, outcome := range a.analyzer.Outcomes {
result := &AnalyzeResult{
Title: a.Title(),
}
if outcome.Fail != nil {
if outcome.Fail.When == "" {
result.IsFail = true
result.Message = outcome.Fail.Message
result.URI = outcome.Fail.URI
return result, nil
} else {
isMatch, out, err := a.compareNodeMetricConditionalsToStats(outcome.Fail.When, summaries)
if err != nil {
return nil, errors.Wrap(err, "failed to compare node metrics conditional with summary stats")
}
if isMatch {
result.IsFail = true
result.Message = renderTemplate(outcome.Fail.Message, out)
result.URI = outcome.Fail.URI
return result, nil
}
}
} else if outcome.Warn != nil {
if outcome.Warn.When == "" {
result.IsWarn = true
result.Message = outcome.Warn.Message
result.URI = outcome.Warn.URI
return result, nil
} else {
isMatch, out, err := a.compareNodeMetricConditionalsToStats(outcome.Warn.When, summaries)
if err != nil {
return nil, errors.Wrap(err, "failed to compare node metrics conditional with summary stats")
}
if isMatch {
result.IsWarn = true
result.Message = renderTemplate(outcome.Warn.Message, out)
result.URI = outcome.Warn.URI
return result, nil
}
}
} else if outcome.Pass != nil {
if outcome.Pass.When == "" {
result.IsPass = true
result.Message = outcome.Pass.Message
result.URI = outcome.Pass.URI
return result, nil
} else {
isMatch, out, err := a.compareNodeMetricConditionalsToStats(outcome.Pass.When, summaries)
if err != nil {
return nil, errors.Wrap(err, "failed to compare node metrics conditional with summary stats")
}
if isMatch {
result.IsPass = true
result.Message = renderTemplate(outcome.Pass.Message, out)
result.URI = outcome.Pass.URI
return result, nil
}
}
}
}
return nil, nil
}
func (a *AnalyzeNodeMetrics) findPVCUsageStats(summaries []kubeletv1alpha1.Summary) ([]pvcUsageStats, error) {
// We just collect usage percentages for now. If other stats are needed, we can add them.
stats := []pvcUsageStats{}
var nameRegex *regexp.Regexp
var ns string
var err error
pvcFilter := a.analyzer.Filters.PVC
if pvcFilter != nil {
if pvcFilter.NameRegex != "" {
nameRegex, err = regexp.Compile(pvcFilter.NameRegex)
if err != nil {
return nil, errors.Wrap(err, "failed to compile PVC name regex")
}
}
ns = pvcFilter.Namespace
}
// Analyze PVCs
for _, summary := range summaries {
for i := range summary.Pods {
pod := summary.Pods[i]
if ns != "" && ns != pod.PodRef.Namespace {
klog.V(2).Infof("Skipping pvcs in %s/%s pod due to namespace filter", pod.PodRef.Namespace, pod.PodRef.Name)
continue
}
for j := range pod.VolumeStats {
volume := pod.VolumeStats[j]
// This is a persistent volume
if volume.PVCRef != nil {
if nameRegex != nil && !nameRegex.MatchString(volume.PVCRef.Name) {
klog.V(2).Infof("Skipping pvc %s/%s due to name regex filter", volume.PVCRef.Namespace, volume.PVCRef.Name)
continue
}
// Calculate the usage
pvcName := fmt.Sprintf("%s/%s", volume.PVCRef.Namespace, volume.PVCRef.Name)
used := volume.UsedBytes
capacity := volume.CapacityBytes
if used != nil && capacity != nil {
pvcUsedPercentage := float64(*used) / float64(*capacity) * 100
stats = append(stats, pvcUsageStats{
PvcName: pvcName,
Used: pvcUsedPercentage,
})
klog.V(2).Infof("PVC usage for %s: %0.2f%%", pvcName, pvcUsedPercentage)
} else {
klog.V(2).Infof("Missing capacity or used bytes for PVC %s", pvcName)
}
}
}
}
}
return stats, nil
}
// compareNodeMetricConditionalsToStats compares the conditional with the collected node metrics
// and returns true if the conditional is met. At the moment we only support comparing PVC usage
func (a *AnalyzeNodeMetrics) compareNodeMetricConditionalsToStats(conditional string, summaries []kubeletv1alpha1.Summary) (bool, nodeMetricsComparisonResults, error) {
klog.V(2).Infof("Comparing node metrics with conditional: %s", conditional)
parts := strings.Split(strings.TrimSpace(conditional), " ")
out := nodeMetricsComparisonResults{}
if len(parts) != 3 {
return false, out, errors.New("unable to parse conditional")
}
switch parts[0] {
case "pvcUsedPercentage":
// e.g pvcUsedPercentage >= 50.4
klog.V(2).Infof("Analyzing volume usage stats for PVCs")
op, err := ParseComparisonOperator(parts[1])
if err != nil {
return false, out, errors.Wrap(err, "failed to parse comparison operator")
}
expected, err := strconv.ParseFloat(parts[2], 64)
if err != nil {
return false, out, errors.Wrap(err, "failed to parse bool")
}
// Pick all PVCs from all summaries. Filters will be applied here
pvcUsageStats, err := a.findPVCUsageStats(summaries)
if err != nil {
return false, out, errors.Wrap(err, "failed to find PVC usage stats")
}
matchedPVCs := []string{}
for _, pvcUsage := range pvcUsageStats {
value := pvcUsage.Used
switch op {
case Equal:
if value == expected {
matchedPVCs = append(matchedPVCs, pvcUsage.PvcName)
}
case NotEqual:
if value != expected {
matchedPVCs = append(matchedPVCs, pvcUsage.PvcName)
}
case LessThan:
if value < expected {
matchedPVCs = append(matchedPVCs, pvcUsage.PvcName)
}
case GreaterThan:
if value > expected {
matchedPVCs = append(matchedPVCs, pvcUsage.PvcName)
}
case LessThanOrEqual:
if value <= expected {
matchedPVCs = append(matchedPVCs, pvcUsage.PvcName)
}
case GreaterThanOrEqual:
if value >= expected {
matchedPVCs = append(matchedPVCs, pvcUsage.PvcName)
}
}
}
// Concatenate all matched PVC names
out.PVC = pvcTemplateData{
Names: matchedPVCs,
ConcatenatedNames: strings.Join(matchedPVCs, ", "),
}
return len(matchedPVCs) > 0, out, nil
}
return false, out, errors.New("unknown node metric conditional")
}
func renderTemplate(tmpMsg string, data any) string {
if data == nil {
return tmpMsg
}
t, err := template.New("msg").Parse(tmpMsg)
if err != nil {
klog.V(2).Infof("Failed to parse template: %s", err)
return tmpMsg
}
var m bytes.Buffer
err = t.Execute(&m, data)
if err != nil {
klog.V(2).Infof("Failed to execute template: %s", err)
return tmpMsg
}
return m.String()
}
+288
View File
@@ -0,0 +1,288 @@
package analyzer
import (
"testing"
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
"github.com/stretchr/testify/assert"
kubeletv1alpha1 "k8s.io/kubelet/pkg/apis/stats/v1alpha1"
utilptr "k8s.io/utils/ptr"
)
func TestAnalyzeNodeMetrics_findPVCUsageStats(t *testing.T) {
tests := []struct {
name string
analyzer troubleshootv1beta2.NodeMetricsAnalyze
summaries []kubeletv1alpha1.Summary
want []pvcUsageStats
wantErr bool
}{
{
name: "no summaries",
summaries: []kubeletv1alpha1.Summary{},
want: []pvcUsageStats{},
},
{
name: "one summary",
summaries: []kubeletv1alpha1.Summary{
{
Pods: []kubeletv1alpha1.PodStats{
{
PodRef: kubeletv1alpha1.PodReference{
Namespace: "default",
Name: "my-pod",
},
VolumeStats: []kubeletv1alpha1.VolumeStats{
{
Name: "volume-1",
PVCRef: &kubeletv1alpha1.PVCReference{
Namespace: "default",
Name: "my-pvc",
},
FsStats: kubeletv1alpha1.FsStats{
AvailableBytes: utilptr.To(uint64(20)),
UsedBytes: utilptr.To(uint64(80)),
CapacityBytes: utilptr.To(uint64(100)),
},
},
},
},
},
},
},
want: []pvcUsageStats{
{
Used: 80,
PvcName: "default/my-pvc",
},
},
},
{
name: "one summary with namespace filter",
analyzer: troubleshootv1beta2.NodeMetricsAnalyze{
Filters: troubleshootv1beta2.NodeMetricsAnalyzeFilters{
PVC: &troubleshootv1beta2.PVCRef{
Namespace: "another-namespace",
},
},
},
summaries: []kubeletv1alpha1.Summary{
{
Pods: []kubeletv1alpha1.PodStats{
{
PodRef: kubeletv1alpha1.PodReference{
Namespace: "default",
Name: "my-pod",
},
VolumeStats: []kubeletv1alpha1.VolumeStats{
{
Name: "volume-1",
PVCRef: &kubeletv1alpha1.PVCReference{
Namespace: "default",
Name: "my-pvc",
},
FsStats: kubeletv1alpha1.FsStats{
AvailableBytes: utilptr.To(uint64(20)),
UsedBytes: utilptr.To(uint64(80)),
CapacityBytes: utilptr.To(uint64(100)),
},
},
},
},
},
},
},
want: []pvcUsageStats{},
},
{
name: "one summary with name regex filter",
analyzer: troubleshootv1beta2.NodeMetricsAnalyze{
Filters: troubleshootv1beta2.NodeMetricsAnalyzeFilters{
PVC: &troubleshootv1beta2.PVCRef{
NameRegex: ".*other.*",
},
},
},
summaries: []kubeletv1alpha1.Summary{
{
Pods: []kubeletv1alpha1.PodStats{
{
PodRef: kubeletv1alpha1.PodReference{
Namespace: "default",
Name: "my-pod",
},
VolumeStats: []kubeletv1alpha1.VolumeStats{
{
Name: "volume-1",
PVCRef: &kubeletv1alpha1.PVCReference{
Namespace: "default",
Name: "my-pvc",
},
FsStats: kubeletv1alpha1.FsStats{
AvailableBytes: utilptr.To(uint64(20)),
UsedBytes: utilptr.To(uint64(80)),
CapacityBytes: utilptr.To(uint64(100)),
},
},
{
Name: "volume-1",
PVCRef: &kubeletv1alpha1.PVCReference{
Namespace: "default",
Name: "my-other-pvc",
},
FsStats: kubeletv1alpha1.FsStats{
AvailableBytes: utilptr.To(uint64(25)),
UsedBytes: utilptr.To(uint64(75)),
CapacityBytes: utilptr.To(uint64(100)),
},
},
},
},
},
},
},
want: []pvcUsageStats{
{
Used: 75,
PvcName: "default/my-other-pvc",
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
a := &AnalyzeNodeMetrics{
analyzer: &tt.analyzer,
}
got, err := a.findPVCUsageStats(tt.summaries)
assert.Equalf(t, tt.wantErr, err != nil, "AnalyzeNodeMetrics.findPVCUsageStats() error = %v, wantErr %v", err, tt.wantErr)
assert.Equal(t, tt.want, got)
})
}
}
func TestAnalyzeNodeMetrics_Analyze(t *testing.T) {
tests := []struct {
name string
analyzer troubleshootv1beta2.NodeMetricsAnalyze
nodeMetrics string
want []*AnalyzeResult
wantErr bool
}{
{
name: "no node metrics",
analyzer: troubleshootv1beta2.NodeMetricsAnalyze{
Filters: troubleshootv1beta2.NodeMetricsAnalyzeFilters{},
},
nodeMetrics: "",
wantErr: true,
},
{
name: "invalid node metrics",
analyzer: troubleshootv1beta2.NodeMetricsAnalyze{
Filters: troubleshootv1beta2.NodeMetricsAnalyzeFilters{},
},
nodeMetrics: "invalid",
wantErr: true,
},
{
name: "no summaries",
analyzer: troubleshootv1beta2.NodeMetricsAnalyze{
Filters: troubleshootv1beta2.NodeMetricsAnalyzeFilters{},
},
nodeMetrics: "{}",
want: []*AnalyzeResult{},
},
{
name: "one summary with name regex filter",
analyzer: troubleshootv1beta2.NodeMetricsAnalyze{
Outcomes: []*troubleshootv1beta2.Outcome{
{
Fail: &troubleshootv1beta2.SingleOutcome{
When: "pvcUsedPercentage >= 75",
Message: "PVC space usage is too high for pvcs [{{ .PVC.ConcatenatedNames }}]",
},
},
{
Pass: &troubleshootv1beta2.SingleOutcome{
Message: "No PVCs are using more than 80% of storage",
},
},
},
Filters: troubleshootv1beta2.NodeMetricsAnalyzeFilters{
PVC: &troubleshootv1beta2.PVCRef{
NameRegex: ".*other.*",
},
},
},
nodeMetrics: `{
"pods": [
{
"podRef": {
"name": "my-pod",
"namespace": "my-namespace"
},
"volume": [
{
"capacityBytes": 100,
"usedBytes": 80,
"pvcRef": {
"name": "backup-pvc",
"namespace": "my-namespace"
}
},
{
"capacityBytes": 100,
"usedBytes": 75,
"pvcRef": {
"name": "another-pvc",
"namespace": "my-namespace"
}
},
{
"capacityBytes": 100,
"usedBytes": 80,
"pvcRef": {
"name": "the-other-pvc",
"namespace": "my-namespace"
}
},
{
"capacityBytes": 100,
"usedBytes": 65,
"pvcRef": {
"name": "to-other-pvc",
"namespace": "my-namespace"
}
}
]
}
]
}`,
want: []*AnalyzeResult{
{
Title: "Node Metrics",
IsFail: true,
Message: "PVC space usage is too high for pvcs [my-namespace/another-pvc, my-namespace/the-other-pvc]",
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
a := &AnalyzeNodeMetrics{
analyzer: &tt.analyzer,
}
filesFn := func(string, []string) (map[string][]byte, error) {
return map[string][]byte{
"node-metrics.json": []byte(tt.nodeMetrics),
}, nil
}
got, err := a.Analyze(nil, filesFn)
assert.Equalf(t, tt.wantErr, err != nil, "AnalyzeNodeMetrics.Analyze() error = %v, wantErr %v", err, tt.wantErr)
assert.Equal(t, tt.want, got)
})
}
}
+18 -14
View File
@@ -17,22 +17,23 @@ import (
)
var Filemap = map[string]string{
"Deployment": constants.CLUSTER_RESOURCES_DEPLOYMENTS,
"StatefulSet": constants.CLUSTER_RESOURCES_STATEFULSETS,
"NetworkPolicy": constants.CLUSTER_RESOURCES_NETWORK_POLICY,
"Pod": constants.CLUSTER_RESOURCES_PODS,
"Ingress": constants.CLUSTER_RESOURCES_INGRESS,
"Service": constants.CLUSTER_RESOURCES_SERVICES,
"ResourceQuota": constants.CLUSTER_RESOURCES_RESOURCE_QUOTA,
"Job": constants.CLUSTER_RESOURCES_JOBS,
"PersistentVolumeClaim": constants.CLUSTER_RESOURCES_PVCS,
"deployment": constants.CLUSTER_RESOURCES_DEPLOYMENTS,
"statefulset": constants.CLUSTER_RESOURCES_STATEFULSETS,
"networkpolicy": constants.CLUSTER_RESOURCES_NETWORK_POLICY,
"pod": constants.CLUSTER_RESOURCES_PODS,
"ingress": constants.CLUSTER_RESOURCES_INGRESS,
"service": constants.CLUSTER_RESOURCES_SERVICES,
"resourcequota": constants.CLUSTER_RESOURCES_RESOURCE_QUOTA,
"job": constants.CLUSTER_RESOURCES_JOBS,
"persistentvolumeclaim": constants.CLUSTER_RESOURCES_PVCS,
"pvc": constants.CLUSTER_RESOURCES_PVCS,
"ReplicaSet": constants.CLUSTER_RESOURCES_REPLICASETS,
"Namespace": fmt.Sprintf("%s.json", constants.CLUSTER_RESOURCES_NAMESPACES),
"PersistentVolume": fmt.Sprintf("%s.json", constants.CLUSTER_RESOURCES_PVS),
"replicaset": constants.CLUSTER_RESOURCES_REPLICASETS,
"configmap": constants.CLUSTER_RESOURCES_CONFIGMAPS,
"namespace": fmt.Sprintf("%s.json", constants.CLUSTER_RESOURCES_NAMESPACES),
"persistentvolume": fmt.Sprintf("%s.json", constants.CLUSTER_RESOURCES_PVS),
"pv": fmt.Sprintf("%s.json", constants.CLUSTER_RESOURCES_PVS),
"Node": fmt.Sprintf("%s.json", constants.CLUSTER_RESOURCES_NODES),
"StorageClass": fmt.Sprintf("%s.json", constants.CLUSTER_RESOURCES_STORAGE_CLASS),
"node": fmt.Sprintf("%s.json", constants.CLUSTER_RESOURCES_NODES),
"storageclass": fmt.Sprintf("%s.json", constants.CLUSTER_RESOURCES_STORAGE_CLASS),
}
type AnalyzeClusterResource struct {
@@ -66,6 +67,9 @@ func FindResource(kind string, clusterScoped bool, namespace string, name string
var datapath string
// lowercase the kind to avoid case sensitivity
kind = strings.ToLower(kind)
resourceLocation, ok := Filemap[kind]
if !ok {
+14 -4
View File
@@ -21,13 +21,13 @@ func Test_findResource(t *testing.T) {
resourceExists: true,
analyzer: troubleshootv1beta2.ClusterResource{
CollectorName: "Check namespaced resource",
Kind: "Deployment",
Kind: "deployment",
Namespace: "kube-system",
Name: "coredns",
},
},
{
name: "check default fallthrough",
name: "check default fallthrough with case insensitivity",
resourceExists: true,
analyzer: troubleshootv1beta2.ClusterResource{
CollectorName: "Check namespaced resource",
@@ -40,7 +40,7 @@ func Test_findResource(t *testing.T) {
resourceExists: true,
analyzer: troubleshootv1beta2.ClusterResource{
CollectorName: "Check namespaced resource",
Kind: "Node",
Kind: "node",
ClusterScoped: true,
Name: "repldev-marc",
},
@@ -50,11 +50,21 @@ func Test_findResource(t *testing.T) {
resourceExists: false,
analyzer: troubleshootv1beta2.ClusterResource{
CollectorName: "Check namespaced resource",
Kind: "Node",
Kind: "node",
ClusterScoped: true,
Name: "resource-does-not-exist",
},
},
{
name: "configmap does exist",
resourceExists: true,
analyzer: troubleshootv1beta2.ClusterResource{
CollectorName: "Check namespaced resource",
Kind: "configmap",
Namespace: "kube-public",
Name: "kube-root-ca.crt",
},
},
}
for _, test := range tests {
-19
View File
@@ -1,19 +1,15 @@
package analyzer
import (
"bufio"
"bytes"
"fmt"
"path/filepath"
"reflect"
"strings"
"github.com/pkg/errors"
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
"github.com/replicatedhq/troubleshoot/pkg/collect"
longhornv1beta1 "github.com/replicatedhq/troubleshoot/pkg/longhorn/apis/longhorn/v1beta1"
longhorntypes "github.com/replicatedhq/troubleshoot/pkg/longhorn/types"
"github.com/replicatedhq/troubleshoot/pkg/redact"
"gopkg.in/yaml.v2"
)
@@ -241,21 +237,6 @@ func analyzeLonghornEngine(engine *longhornv1beta1.Engine) *AnalyzeResult {
return result
}
func stripRedactedLines(yaml []byte) []byte {
buf := bytes.NewBuffer(yaml)
scanner := bufio.NewScanner(buf)
out := []byte{}
for scanner.Scan() {
line := strings.ReplaceAll(scanner.Text(), redact.MASK_TEXT, "HIDDEN")
out = append(out, []byte(line)...)
out = append(out, '\n')
}
return out
}
func analyzeLonghornReplicaChecksums(volumeName string, checksums []map[string]string) *AnalyzeResult {
result := &AnalyzeResult{
Title: fmt.Sprintf("Longhorn Volume Replica Corruption: %s", volumeName),
+4
View File
@@ -101,6 +101,10 @@ func analyzeOneReplicaSetStatus(analyzer *troubleshootv1beta2.ReplicaSetStatus,
}
}
if result == nil {
return nil, nil
}
return []*AnalyzeResult{result}, nil
}
+62
View File
@@ -0,0 +1,62 @@
package analyzer
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// ResticRepositorySpec is the specification for a ResticRepository.
type ResticRepositorySpec struct {
// VolumeNamespace is the namespace this restic repository contains
// pod volume backups for.
VolumeNamespace string `json:"volumeNamespace"`
// BackupStorageLocation is the name of the BackupStorageLocation
// that should contain this repository.
BackupStorageLocation string `json:"backupStorageLocation"`
// ResticIdentifier is the full restic-compatible string for identifying
// this repository.
ResticIdentifier string `json:"resticIdentifier"`
// MaintenanceFrequency is how often maintenance should be run.
MaintenanceFrequency metav1.Duration `json:"maintenanceFrequency"`
}
// ResticRepositoryPhase represents the lifecycle phase of a ResticRepository.
// +kubebuilder:validation:Enum=New;Ready;NotReady
type ResticRepositoryPhase string
const (
ResticRepositoryPhaseNew ResticRepositoryPhase = "New"
ResticRepositoryPhaseReady ResticRepositoryPhase = "Ready"
ResticRepositoryPhaseNotReady ResticRepositoryPhase = "NotReady"
)
// ResticRepositoryStatus is the current status of a ResticRepository.
type ResticRepositoryStatus struct {
// Phase is the current state of the ResticRepository.
// +optional
Phase ResticRepositoryPhase `json:"phase,omitempty"`
// Message is a message about the current status of the ResticRepository.
// +optional
Message string `json:"message,omitempty"`
// LastMaintenanceTime is the last time maintenance was run.
// +optional
// +nullable
LastMaintenanceTime *metav1.Time `json:"lastMaintenanceTime,omitempty"`
}
type ResticRepository struct {
metav1.TypeMeta `json:",inline"`
// +optional
metav1.ObjectMeta `json:"metadata,omitempty"`
// +optional
Spec ResticRepositorySpec `json:"spec,omitempty"`
// +optional
Status ResticRepositoryStatus `json:"status,omitempty"`
}
+738
View File
@@ -0,0 +1,738 @@
package analyzer
import (
"encoding/json"
"fmt"
"path/filepath"
"strings"
appsV1 "k8s.io/api/apps/v1"
restic_types "github.com/replicatedhq/troubleshoot/pkg/analyze/types"
"golang.org/x/mod/semver"
"github.com/pkg/errors"
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
velerov1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
)
type AnalyzeVelero struct {
analyzer *troubleshootv1beta2.VeleroAnalyze
}
func (a *AnalyzeVelero) Title() string {
title := a.analyzer.CheckName
if title == "" {
title = "Velero"
}
return title
}
func (a *AnalyzeVelero) IsExcluded() (bool, error) {
return isExcluded(a.analyzer.Exclude)
}
func (a *AnalyzeVelero) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) {
results, err := a.veleroStatus(a.analyzer, getFile, findFiles)
if err != nil {
return nil, err
}
for i := range results {
results[i].Strict = a.analyzer.Strict.BoolOrDefaultFalse()
}
return results, nil
}
func (a *AnalyzeVelero) veleroStatus(analyzer *troubleshootv1beta2.VeleroAnalyze, getFileContents getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) {
excludeFiles := []string{}
results := []*AnalyzeResult{}
oldVeleroRepoType := false
veleroVersion, err := getVeleroVersion(excludeFiles, findFiles)
if err != nil {
return nil, errors.Wrap(err, "Unable to find velero deployment")
}
// Check if the version string is valid erer
if !semver.IsValid(veleroVersion) {
return nil, errors.Errorf("Invalid velero semver: %s", veleroVersion)
}
// check if veleroVersion is less than 1.10.x
compareResult := semver.Compare(veleroVersion, "1.10.0")
if compareResult < 0 {
oldVeleroRepoType = true
}
if oldVeleroRepoType == true {
// old velero (v1.9.x) has a BackupRepositoryTypeRestic
// get resticrepositories.velero.io
resticRepositoriesDir := GetVeleroResticRepositoriesDirectory()
resticRepositoriesGlob := filepath.Join(resticRepositoriesDir, "*.json")
resticRepositoriesJson, err := findFiles(resticRepositoriesGlob, excludeFiles)
if err != nil {
return nil, errors.Wrapf(err, "failed to find velero restic repositories files under %s", resticRepositoriesDir)
}
resticRepositories := []*restic_types.ResticRepository{}
for key, resticRepositoryJson := range resticRepositoriesJson {
var resticRepositoryArray []*restic_types.ResticRepository
err := json.Unmarshal(resticRepositoryJson, &resticRepositories)
if err != nil {
return nil, errors.Wrapf(err, "failed to unmarshal restic repository json from %s", key)
}
resticRepositories = append(resticRepositories, resticRepositoryArray...)
}
results = append(results, analyzeResticRepositories(resticRepositories)...)
} else {
// velerov1.Version
// get backuprepositories.velero.io
backupRepositoriesDir := GetVeleroBackupRepositoriesDirectory()
backupRepositoriesGlob := filepath.Join(backupRepositoriesDir, "*.json")
backupRepositoriesJson, err := findFiles(backupRepositoriesGlob, excludeFiles)
if err != nil {
return nil, errors.Wrapf(err, "failed to find velero backup repositories files under %s", backupRepositoriesDir)
}
backupRepositories := []*velerov1.BackupRepository{}
for key, backupRepositoryJson := range backupRepositoriesJson {
var backupRepositoryArray []*velerov1.BackupRepository
err := json.Unmarshal(backupRepositoryJson, &backupRepositoryArray)
if err != nil {
return nil, errors.Wrapf(err, "failed to unmarshal backup repository json from %s", key)
}
backupRepositories = append(backupRepositories, backupRepositoryArray...)
}
results = append(results, analyzeBackupRepositories(backupRepositories)...)
}
// get backups.velero.io
backupsDir := GetVeleroBackupsDirectory()
backupsGlob := filepath.Join(backupsDir, "*.json")
veleroJSONs, err := findFiles(backupsGlob, excludeFiles)
if err != nil {
return nil, errors.Wrapf(err, "failed to find velero backup files")
}
backups := []*velerov1.Backup{}
for _, veleroJSON := range veleroJSONs {
if err != nil {
return nil, errors.Wrapf(err, "failed to read velero backup file %s", veleroJSON)
}
var veleroBackups []*velerov1.Backup
err = json.Unmarshal(veleroJSON, &veleroBackups)
if err != nil {
return nil, errors.Wrapf(err, "failed to unmarshal velero backup file %s", veleroJSON)
}
backups = append(backups, veleroBackups...)
}
// get backupstoragelocations.velero.io
backupStorageLocationsDir := GetVeleroBackupStorageLocationsDirectory()
backupStorageLocationsGlob := filepath.Join(backupStorageLocationsDir, "*.json")
backupStorageLocationsJson, err := findFiles(backupStorageLocationsGlob, excludeFiles)
if err != nil {
return nil, errors.Wrapf(err, "failed to find velero backup storage locations files under %s", backupStorageLocationsDir)
}
backupStorageLocations := []*velerov1.BackupStorageLocation{}
for key, backupStorageLocationJson := range backupStorageLocationsJson {
var backupStorageLocationArray []*velerov1.BackupStorageLocation
err := json.Unmarshal(backupStorageLocationJson, &backupStorageLocationArray)
if err != nil {
return nil, errors.Wrapf(err, "failed to unmarshal backup storage location json from %s", key)
}
backupStorageLocations = append(backupStorageLocations, backupStorageLocationArray...)
}
// get deletebackuprequests.velero.io
deleteBackupRequestsDir := GetVeleroDeleteBackupRequestsDirectory()
deleteBackupRequestsGlob := filepath.Join(deleteBackupRequestsDir, "*.json")
deleteBackupRequestsJson, err := findFiles(deleteBackupRequestsGlob, excludeFiles)
if err != nil {
return nil, errors.Wrapf(err, "failed to find velero delete backup requests files under %s", deleteBackupRequestsDir)
}
deleteBackupRequests := []*velerov1.DeleteBackupRequest{}
for key, deleteBackupRequestJson := range deleteBackupRequestsJson {
var deleteBackupRequestArray []*velerov1.DeleteBackupRequest
err := json.Unmarshal(deleteBackupRequestJson, &deleteBackupRequestArray)
if err != nil {
return nil, errors.Wrapf(err, "failed to unmarshal delete backup request json from %s", key)
}
deleteBackupRequests = append(deleteBackupRequests, deleteBackupRequestArray...)
}
// get podvolumebackups.velero.io
podVolumeBackupsDir := GetVeleroPodVolumeBackupsDirectory()
podVolumeBackupsGlob := filepath.Join(podVolumeBackupsDir, "*.json")
podVolumeBackupsJson, err := findFiles(podVolumeBackupsGlob, excludeFiles)
if err != nil {
return nil, errors.Wrapf(err, "failed to find velero pod volume backups files under %s", podVolumeBackupsDir)
}
podVolumeBackups := []*velerov1.PodVolumeBackup{}
for key, podVolumeBackupJson := range podVolumeBackupsJson {
var podVolumeBackupArray []*velerov1.PodVolumeBackup
err := json.Unmarshal(podVolumeBackupJson, &podVolumeBackupArray)
if err != nil {
return nil, errors.Wrapf(err, "failed to unmarshal pod volume backup json from %s", key)
}
podVolumeBackups = append(podVolumeBackups, podVolumeBackupArray...)
}
// get podvolumerestores.velero.io
podVolumeRestoresDir := GetVeleroPodVolumeRestoresDirectory()
podVolumeRestoresGlob := filepath.Join(podVolumeRestoresDir, "*.json")
podVolumeRestoresJson, err := findFiles(podVolumeRestoresGlob, excludeFiles)
if err != nil {
return nil, errors.Wrapf(err, "failed to find velero pod volume restores files under %s", podVolumeRestoresDir)
}
podVolumeRestores := []*velerov1.PodVolumeRestore{}
for key, podVolumeRestoreJson := range podVolumeRestoresJson {
var podVolumeRestoreArray []*velerov1.PodVolumeRestore
err := json.Unmarshal(podVolumeRestoreJson, &podVolumeRestoreArray)
if err != nil {
return nil, errors.Wrapf(err, "failed to unmarshal pod volume restore json from %s", key)
}
podVolumeRestores = append(podVolumeRestores, podVolumeRestoreArray...)
}
// get restores.velero.io
restoresDir := GetVeleroRestoresDirectory()
restoresGlob := filepath.Join(restoresDir, "*.json")
restoresJson, err := findFiles(restoresGlob, excludeFiles)
if err != nil {
return nil, errors.Wrapf(err, "failed to find velero restores files under %s", restoresDir)
}
restores := []*velerov1.Restore{}
for key, restoreJson := range restoresJson {
var restoreArray []*velerov1.Restore
err := json.Unmarshal(restoreJson, &restoreArray)
if err != nil {
return nil, errors.Wrapf(err, "failed to unmarshal restore json from %s", key)
}
restores = append(restores, restoreArray...)
}
// get schedules.velero.io
schedulesDir := GetVeleroSchedulesDirectory()
schedulesGlob := filepath.Join(schedulesDir, "*.json")
schedulesJson, err := findFiles(schedulesGlob, excludeFiles)
if err != nil {
return nil, errors.Wrapf(err, "failed to find velero schedules files under %s", schedulesDir)
}
schedules := []*velerov1.Schedule{}
for key, scheduleJson := range schedulesJson {
var scheduleArray []*velerov1.Schedule
err := json.Unmarshal(scheduleJson, &scheduleArray)
if err != nil {
return nil, errors.Wrapf(err, "failed to unmarshal schedule json from %s", key)
}
schedules = append(schedules, scheduleArray...)
}
// get serverstatusrequests.velero.io
serverStatusRequestsDir := GetVeleroServerStatusRequestsDirectory()
serverStatusRequestsGlob := filepath.Join(serverStatusRequestsDir, "*.json")
serverStatusRequestsJson, err := findFiles(serverStatusRequestsGlob, excludeFiles)
if err != nil {
return nil, errors.Wrapf(err, "failed to find velero server status requests files under %s", serverStatusRequestsDir)
}
serverStatusRequests := []*velerov1.ServerStatusRequest{}
for key, serverStatusRequestJson := range serverStatusRequestsJson {
var serverStatusRequestArray []*velerov1.ServerStatusRequest
err := json.Unmarshal(serverStatusRequestJson, &serverStatusRequestArray)
if err != nil {
return nil, errors.Wrapf(err, "failed to unmarshal server status request json from %s", key)
}
serverStatusRequests = append(serverStatusRequests, serverStatusRequestArray...)
}
// get volumesnapshotlocations.velero.io
volumeSnapshotLocationsDir := GetVeleroVolumeSnapshotLocationsDirectory()
volumeSnapshotLocationsGlob := filepath.Join(volumeSnapshotLocationsDir, "*.json")
volumeSnapshotLocationsJson, err := findFiles(volumeSnapshotLocationsGlob, excludeFiles)
if err != nil {
return nil, errors.Wrapf(err, "failed to find velero volume snapshot locations files under %s", volumeSnapshotLocationsDir)
}
volumeSnapshotLocations := []*velerov1.VolumeSnapshotLocation{}
for key, volumeSnapshotLocationJson := range volumeSnapshotLocationsJson {
var volumeSnapshotLocationArray []*velerov1.VolumeSnapshotLocation
err := json.Unmarshal(volumeSnapshotLocationJson, &volumeSnapshotLocationArray)
if err != nil {
return nil, errors.Wrapf(err, "failed to unmarshal volume snapshot location json from %s", key)
}
volumeSnapshotLocations = append(volumeSnapshotLocations, volumeSnapshotLocationArray...)
}
logsDir := GetVeleroLogsDirectory()
logsGlob := filepath.Join(logsDir, "node-agent*", "*.log")
nodeAgentlogs, err := findFiles(logsGlob, excludeFiles)
if err != nil {
return nil, errors.Wrapf(err, "failed to find velero logs files under %s", logsDir)
}
veleroLogsGlob := filepath.Join(logsDir, "velero*", "*.log")
veleroLogs, err := findFiles(veleroLogsGlob, excludeFiles)
results = append(results, analyzeLogs(nodeAgentlogs, "node-agent*")...)
results = append(results, analyzeLogs(veleroLogs, "velero*")...)
results = append(results, analyzeBackups(backups)...)
results = append(results, analyzeBackupStorageLocations(backupStorageLocations)...)
results = append(results, analyzeDeleteBackupRequests(deleteBackupRequests)...)
results = append(results, analyzePodVolumeBackups(podVolumeBackups)...)
results = append(results, analyzePodVolumeRestores(podVolumeRestores)...)
results = append(results, analyzeRestores(restores)...)
results = append(results, analyzeSchedules(schedules)...)
results = append(results, analyzeVolumeSnapshotLocations(volumeSnapshotLocations)...)
return aggregateResults(results), nil
}
func analyzeBackupRepositories(backupRepositories []*velerov1.BackupRepository) []*AnalyzeResult {
results := []*AnalyzeResult{}
readyCount := 0
backupRepositoriesResult := &AnalyzeResult{
Title: "At least 1 Backup Repository configured",
}
if len(backupRepositories) == 0 {
backupRepositoriesResult.IsFail = true
backupRepositoriesResult.Message = "No backup repositories configured"
} else {
for _, backupRepository := range backupRepositories {
if backupRepository.Status.Phase != velerov1.BackupRepositoryPhaseReady {
result := &AnalyzeResult{
Title: fmt.Sprintf("Backup Repository %s", backupRepository.Name),
}
result.Message = fmt.Sprintf("Backup Repository [%s] is in phase %s", backupRepository.Name, backupRepository.Status.Phase)
result.IsWarn = true
results = append(results, result)
} else {
readyCount++
}
}
if readyCount > 0 {
backupRepositoriesResult.IsPass = true
backupRepositoriesResult.Message = fmt.Sprintf("Found %d backup repositories configured and %d Ready", len(backupRepositories), readyCount)
} else {
backupRepositoriesResult.IsWarn = true
backupRepositoriesResult.Message = fmt.Sprintf("Found %d configured backup repositories, but none are ready", len(backupRepositories))
}
}
results = append(results, backupRepositoriesResult)
return results
}
func analyzeResticRepositories(resticRepositories []*restic_types.ResticRepository) []*AnalyzeResult {
results := []*AnalyzeResult{}
readyCount := 0
resticRepositoriesResult := &AnalyzeResult{
Title: "At least 1 Restic Repository configured",
}
if len(resticRepositories) == 0 {
resticRepositoriesResult.IsFail = true
resticRepositoriesResult.Message = "No restic repositories configured"
} else {
for _, resticRepository := range resticRepositories {
if resticRepository.Status.Phase != restic_types.ResticRepositoryPhaseReady {
result := &AnalyzeResult{
Title: fmt.Sprintf("Restic Repository %s", resticRepository.GetName()),
}
result.Message = fmt.Sprintf("Restic Repository [%s] is in phase %s", resticRepository.Name, resticRepository.Status.Phase)
result.IsWarn = true
results = append(results, result)
} else {
readyCount++
}
}
if readyCount > 0 {
resticRepositoriesResult.IsPass = true
resticRepositoriesResult.Message = fmt.Sprintf("Found %d restic repositories configured and %d Ready", len(resticRepositories), readyCount)
} else {
resticRepositoriesResult.IsWarn = true
resticRepositoriesResult.Message = fmt.Sprintf("Found %d configured restic repositories, but none are ready", len(resticRepositories))
}
}
results = append(results, resticRepositoriesResult)
return results
}
func analyzeBackups(backups []*velerov1.Backup) []*AnalyzeResult {
results := []*AnalyzeResult{}
failedPhases := map[velerov1.BackupPhase]bool{
velerov1.BackupPhaseFailed: true,
velerov1.BackupPhasePartiallyFailed: true,
velerov1.BackupPhaseFailedValidation: true,
}
for _, backup := range backups {
if failedPhases[backup.Status.Phase] {
result := &AnalyzeResult{
Title: fmt.Sprintf("Backup %s", backup.Name),
}
result.IsFail = true
result.Message = fmt.Sprintf("Backup %s phase is %s", backup.Name, backup.Status.Phase)
results = append(results, result)
}
}
if len(backups) > 0 {
results = append(results, &AnalyzeResult{
Title: "Velero Backups",
IsPass: true,
Message: fmt.Sprintf("Found %d backups", len(backups)),
})
}
return results
}
func analyzeBackupStorageLocations(backupStorageLocations []*velerov1.BackupStorageLocation) []*AnalyzeResult {
results := []*AnalyzeResult{}
availableCount := 0
bslResult := &AnalyzeResult{
Title: "At least 1 Backup Storage Location configured",
}
if len(backupStorageLocations) == 0 {
bslResult.IsFail = true
bslResult.Message = "No backup storage locations configured"
} else {
for _, backupStorageLocation := range backupStorageLocations {
if backupStorageLocation.Status.Phase != velerov1.BackupStorageLocationPhaseAvailable {
result := &AnalyzeResult{
Title: fmt.Sprintf("Backup Storage Location %s", backupStorageLocation.Name),
}
result.Message = fmt.Sprintf("Backup Storage Location [%s] is in phase %s", backupStorageLocation.Name, backupStorageLocation.Status.Phase)
result.IsWarn = true
results = append(results, result)
} else {
availableCount++
}
}
if availableCount > 0 {
bslResult.IsPass = true
bslResult.Message = fmt.Sprintf("Found %d backup storage locations configured and %d Available", len(backupStorageLocations), availableCount)
} else {
bslResult.IsWarn = true
bslResult.Message = fmt.Sprintf("Found %d configured backup storage locations, but none are available", len(backupStorageLocations))
}
}
results = append(results, bslResult)
return results
}
func analyzeDeleteBackupRequests(deleteBackupRequests []*velerov1.DeleteBackupRequest) []*AnalyzeResult {
results := []*AnalyzeResult{}
inProgressCount := 0
if len(deleteBackupRequests) > 0 {
for _, deleteBackupRequest := range deleteBackupRequests {
if deleteBackupRequest.Status.Phase == velerov1.DeleteBackupRequestPhaseInProgress {
inProgressCount++
}
}
if inProgressCount > 0 {
deleteBackupRequestsResult := &AnalyzeResult{
Title: "Delete Backup Requests summary",
}
deleteBackupRequestsResult.IsWarn = true
deleteBackupRequestsResult.Message = fmt.Sprintf("Found %d delete backup requests in progress", inProgressCount)
results = append(results, deleteBackupRequestsResult)
}
}
return results
}
func analyzePodVolumeBackups(podVolumeBackups []*velerov1.PodVolumeBackup) []*AnalyzeResult {
results := []*AnalyzeResult{}
failures := 0
if len(podVolumeBackups) > 0 {
for _, podVolumeBackup := range podVolumeBackups {
if podVolumeBackup.Status.Phase == velerov1.PodVolumeBackupPhaseFailed {
result := &AnalyzeResult{
Title: fmt.Sprintf("Pod Volume Backup %s", podVolumeBackup.Name),
}
result.IsFail = true
result.Message = fmt.Sprintf("Pod Volume Backup %s phase is %s", podVolumeBackup.Name, podVolumeBackup.Status.Phase)
results = append(results, result)
failures++
}
}
if failures == 0 {
results = append(results, &AnalyzeResult{
Title: "Pod Volume Backups",
IsPass: true,
Message: fmt.Sprintf("Found %d pod volume backups", len(podVolumeBackups)),
})
}
}
return results
}
func analyzePodVolumeRestores(podVolumeRestores []*velerov1.PodVolumeRestore) []*AnalyzeResult {
results := []*AnalyzeResult{}
failures := 0
if len(podVolumeRestores) > 0 {
for _, podVolumeRestore := range podVolumeRestores {
if podVolumeRestore.Status.Phase == velerov1.PodVolumeRestorePhaseFailed {
result := &AnalyzeResult{
Title: fmt.Sprintf("Pod Volume Restore %s", podVolumeRestore.Name),
}
result.IsFail = true
result.Message = fmt.Sprintf("Pod Volume Restore %s phase is %s", podVolumeRestore.Name, podVolumeRestore.Status.Phase)
results = append(results, result)
failures++
}
}
if failures == 0 {
results = append(results, &AnalyzeResult{
Title: "Pod Volume Restores",
IsPass: true,
Message: fmt.Sprintf("Found %d pod volume restores", len(podVolumeRestores)),
})
}
}
return results
}
func analyzeRestores(restores []*velerov1.Restore) []*AnalyzeResult {
results := []*AnalyzeResult{}
failures := 0
if len(restores) > 0 {
failedPhases := map[velerov1.RestorePhase]bool{
velerov1.RestorePhaseFailed: true,
velerov1.RestorePhasePartiallyFailed: true,
velerov1.RestorePhaseFailedValidation: true,
}
for _, restore := range restores {
if failedPhases[restore.Status.Phase] {
result := &AnalyzeResult{
Title: fmt.Sprintf("Restore %s", restore.Name),
}
result.IsFail = true
result.Message = fmt.Sprintf("Restore %s phase is %s", restore.Name, restore.Status.Phase)
results = append(results, result)
failures++
}
}
if failures == 0 {
results = append(results, &AnalyzeResult{
Title: "Velero Restores",
IsPass: true,
Message: fmt.Sprintf("Found %d restores", len(restores)),
})
}
}
return results
}
func analyzeSchedules(schedules []*velerov1.Schedule) []*AnalyzeResult {
results := []*AnalyzeResult{}
failures := 0
if len(schedules) > 0 {
for _, schedule := range schedules {
if schedule.Status.Phase == velerov1.SchedulePhaseFailedValidation {
result := &AnalyzeResult{
Title: fmt.Sprintf("Schedule %s", schedule.Name),
}
result.IsFail = true
result.Message = fmt.Sprintf("Schedule %s phase is %s", schedule.Name, schedule.Status.Phase)
results = append(results, result)
failures++
}
}
if failures == 0 {
results = append(results, &AnalyzeResult{
Title: "Velero Schedules",
IsPass: true,
Message: fmt.Sprintf("Found %d schedules", len(schedules)),
})
}
}
return results
}
func analyzeVolumeSnapshotLocations(volumeSnapshotLocations []*velerov1.VolumeSnapshotLocation) []*AnalyzeResult {
results := []*AnalyzeResult{}
failures := 0
if len(volumeSnapshotLocations) > 0 {
for _, volumeSnapshotLocation := range volumeSnapshotLocations {
if volumeSnapshotLocation.Status.Phase == velerov1.VolumeSnapshotLocationPhaseUnavailable {
result := &AnalyzeResult{
Title: fmt.Sprintf("Volume Snapshot Location %s", volumeSnapshotLocation.Name),
}
result.IsFail = true
result.Message = fmt.Sprintf("Volume Snapshot Location %s phase is %s", volumeSnapshotLocation.Name, volumeSnapshotLocation.Status.Phase)
results = append(results, result)
failures++
}
}
if failures == 0 {
results = append(results, &AnalyzeResult{
Title: "Velero Volume Snapshot Locations",
IsPass: true,
Message: fmt.Sprintf("Found %d volume snapshot locations", len(volumeSnapshotLocations)),
})
}
}
return results
}
func analyzeLogs(logs map[string][]byte, kind string) []*AnalyzeResult {
results := []*AnalyzeResult{}
if len(logs) > 0 {
for key, logBytes := range logs {
logContent := string(logBytes)
result := &AnalyzeResult{
Title: fmt.Sprintf("Velero logs for pod [%s]", key),
}
if strings.Contains(logContent, "permission denied") {
result.IsWarn = true
result.Message = fmt.Sprintf("Found 'permission denied' in %s pod log file(s)", kind)
results = append(results, result)
continue
}
if strings.Contains(logContent, "error") || strings.Contains(logContent, "panic") || strings.Contains(logContent, "fatal") {
result.IsWarn = true
result.Message = fmt.Sprintf("Found error|panic|fatal in %s pod log file(s)", kind)
results = append(results, result)
}
}
results = append(results, &AnalyzeResult{
Title: fmt.Sprintf("Velero Logs analysis for kind [%s]", kind),
IsPass: true,
Message: fmt.Sprintf("Found %d log files", len(logs)),
})
}
return results
}
func aggregateResults(results []*AnalyzeResult) []*AnalyzeResult {
out := []*AnalyzeResult{}
resultFailed := false
for _, result := range results {
if result.IsFail {
resultFailed = true
}
out = append(out, result)
}
if len(results) > 0 {
if resultFailed == false {
out = append(out, &AnalyzeResult{
Title: "Velero Status",
IsPass: true,
Message: "Velero setup is healthy",
})
}
if resultFailed == true {
out = append(out, &AnalyzeResult{
Title: "Velero Status",
IsWarn: true,
Message: "Velero setup is not entirely healthy",
})
}
}
return out
}
func getVeleroVersion(excludedFiles []string, findFiles getChildCollectedFileContents) (string, error) {
veleroDeploymentDir := "cluster-resources/deployments"
veleroVersion := ""
veleroDeploymentGlob := filepath.Join(veleroDeploymentDir, "velero.json")
veleroDeploymentJson, err := findFiles(veleroDeploymentGlob, excludedFiles)
if err != nil {
return "", errors.Wrapf(err, "failed to find Velero deployment")
}
if len(veleroDeploymentJson) == 0 {
return "", errors.Errorf("could not find Velero deployment in %s", veleroDeploymentDir)
}
var deploymentList *appsV1.DeploymentList
// should run only once
for key, veleroDeploymentJsonBytes := range veleroDeploymentJson {
err := json.Unmarshal(veleroDeploymentJsonBytes, &deploymentList)
if err != nil {
return "", errors.Wrapf(err, "failed to unmarshal Velero deployment json from %s", key)
}
break
}
if deploymentList == nil {
return "", errors.Errorf("could not find Velero deployment")
}
for _, deployment := range deploymentList.Items {
for _, container := range deployment.Spec.Template.Spec.Containers {
if container.Name == "velero" {
container_image := container.Image
veleroVersion = strings.Split(container_image, ":")[1]
return veleroVersion, nil
}
}
}
return "", errors.Errorf("could not find Velero container in deployment")
}
func GetVeleroBackupsDirectory() string {
return "cluster-resources/custom-resources/backups.velero.io"
}
func GetVeleroBackupRepositoriesDirectory() string {
return "cluster-resources/custom-resources/backuprepositories.velero.io"
}
func GetVeleroBackupStorageLocationsDirectory() string {
return "cluster-resources/custom-resources/backupstoragelocations.velero.io"
}
func GetVeleroDeleteBackupRequestsDirectory() string {
return "cluster-resources/custom-resources/deletebackuprequests.velero.io"
}
func GetVeleroDownloadRequestsDirectory() string {
return "cluster-resources/custom-resources/downloadrequests.velero.io"
}
func GetVeleroLogsDirectory() string {
return "velero/logs"
}
func GetVeleroPodVolumeBackupsDirectory() string {
return "cluster-resources/custom-resources/podvolumebackups.velero.io"
}
func GetVeleroPodVolumeRestoresDirectory() string {
return "cluster-resources/custom-resources/podvolumerestores.velero.io"
}
func GetVeleroRestoresDirectory() string {
return "cluster-resources/custom-resources/restores.velero.io"
}
func GetVeleroSchedulesDirectory() string {
return "cluster-resources/custom-resources/schedules.velero.io"
}
func GetVeleroServerStatusRequestsDirectory() string {
return "cluster-resources/custom-resources/serverstatusrequests.velero.io"
}
func GetVeleroVolumeSnapshotLocationsDirectory() string {
return "cluster-resources/custom-resources/volumesnapshotlocations.velero.io"
}
func GetVeleroResticRepositoriesDirectory() string {
return "cluster-resources/custom-resources/resticrepositories.velero.io"
}
+994
View File
@@ -0,0 +1,994 @@
package analyzer
import (
"encoding/json"
"reflect"
"testing"
"time"
restic_types "github.com/replicatedhq/troubleshoot/pkg/analyze/types"
velerov1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func TestAnalyzeVelero_BackupRepositories(t *testing.T) {
type args struct {
backupRepositories []*velerov1.BackupRepository
}
tests := []struct {
name string
args args
want []*AnalyzeResult
}{
{
name: "no backup repositories",
args: args{
backupRepositories: []*velerov1.BackupRepository{},
},
want: []*AnalyzeResult{
{
Title: "At least 1 Backup Repository configured",
Message: "No backup repositories configured",
IsFail: true,
},
},
},
{
name: "1 backup repository and 1 Ready",
args: args{
backupRepositories: []*velerov1.BackupRepository{
{
Spec: velerov1.BackupRepositorySpec{
BackupStorageLocation: "default",
VolumeNamespace: "velero",
},
Status: velerov1.BackupRepositoryStatus{
Phase: velerov1.BackupRepositoryPhaseReady,
},
},
},
},
want: []*AnalyzeResult{
{
Title: "At least 1 Backup Repository configured",
Message: "Found 1 backup repositories configured and 1 Ready",
IsPass: true,
},
},
},
{
name: "2 backup repositories and 1 Ready",
args: args{
backupRepositories: []*velerov1.BackupRepository{
{
ObjectMeta: metav1.ObjectMeta{
Name: "default-default-restic-245sd",
Namespace: "velero",
},
Spec: velerov1.BackupRepositorySpec{
BackupStorageLocation: "default",
VolumeNamespace: "velero",
},
Status: velerov1.BackupRepositoryStatus{
Phase: velerov1.BackupRepositoryPhaseReady,
},
},
{
ObjectMeta: metav1.ObjectMeta{
Name: "builders-default-restic-jdtd8",
Namespace: "velero",
},
Spec: velerov1.BackupRepositorySpec{
BackupStorageLocation: "builders-default-restic-jdtd8",
VolumeNamespace: "velero",
},
Status: velerov1.BackupRepositoryStatus{
Phase: velerov1.BackupRepositoryPhaseNotReady,
},
},
},
},
want: []*AnalyzeResult{
{
Title: "Backup Repository builders-default-restic-jdtd8",
Message: "Backup Repository [builders-default-restic-jdtd8] is in phase NotReady",
IsWarn: true,
},
{
Title: "At least 1 Backup Repository configured",
Message: "Found 2 backup repositories configured and 1 Ready",
IsPass: true,
},
},
},
{
name: "1 backup repository and none Ready",
args: args{
backupRepositories: []*velerov1.BackupRepository{
{
ObjectMeta: metav1.ObjectMeta{
Name: "default",
Namespace: "velero",
},
Spec: velerov1.BackupRepositorySpec{
BackupStorageLocation: "default",
VolumeNamespace: "velero",
},
Status: velerov1.BackupRepositoryStatus{
Phase: velerov1.BackupRepositoryPhaseNotReady,
},
},
},
},
want: []*AnalyzeResult{
{
Title: "Backup Repository default",
Message: "Backup Repository [default] is in phase NotReady",
IsWarn: true,
},
{
Title: "At least 1 Backup Repository configured",
Message: "Found 1 configured backup repositories, but none are ready",
IsWarn: true,
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := analyzeBackupRepositories(tt.args.backupRepositories); !reflect.DeepEqual(got, tt.want) {
t.Errorf("analyzeBackupRepositories() = %v, want %v", got, tt.want)
}
})
}
}
func TestAnalyzeVelero_ResticRepositories(t *testing.T) {
type args struct {
resticRepositories []*restic_types.ResticRepository
}
tests := []struct {
name string
args args
want []*AnalyzeResult
}{
{
name: "no restic repositories",
args: args{
resticRepositories: []*restic_types.ResticRepository{},
},
want: []*AnalyzeResult{
{
Title: "At least 1 Restic Repository configured",
Message: "No restic repositories configured",
IsFail: true,
},
},
},
{
name: "1 restic repository and 1 Ready",
args: args{
resticRepositories: []*restic_types.ResticRepository{
{
ObjectMeta: metav1.ObjectMeta{
Name: "default-default-restic-245sd",
Namespace: "velero",
},
Spec: restic_types.ResticRepositorySpec{
BackupStorageLocation: "default",
VolumeNamespace: "velero",
},
Status: restic_types.ResticRepositoryStatus{
Phase: restic_types.ResticRepositoryPhaseReady,
},
},
},
},
want: []*AnalyzeResult{
{
Title: "At least 1 Restic Repository configured",
Message: "Found 1 restic repositories configured and 1 Ready",
IsPass: true,
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := analyzeResticRepositories(tt.args.resticRepositories); !reflect.DeepEqual(got, tt.want) {
t.Errorf("analyzeResticRepositories() = %v, want %v", got, tt.want)
}
})
}
}
func TestAnalyzeVelero_Backups(t *testing.T) {
type args struct {
backups []*velerov1.Backup
}
tests := []struct {
name string
args args
want []*AnalyzeResult
}{
{
name: "no backups",
args: args{
backups: []*velerov1.Backup{},
},
want: []*AnalyzeResult{},
},
{
name: "1 backup and 1 Completed",
args: args{
backups: []*velerov1.Backup{
{
ObjectMeta: metav1.ObjectMeta{
Name: "observability-backup",
Namespace: "velero",
},
Spec: velerov1.BackupSpec{
IncludedNamespaces: []string{"monitoring"},
},
Status: velerov1.BackupStatus{
Phase: velerov1.BackupPhaseCompleted,
},
},
},
},
want: []*AnalyzeResult{
{
Title: "Velero Backups",
Message: "Found 1 backups",
IsPass: true,
},
},
},
{
name: "1 backup and 1 Failed",
args: args{
backups: []*velerov1.Backup{
{
ObjectMeta: metav1.ObjectMeta{
Name: "application-backup",
Namespace: "velero",
},
Spec: velerov1.BackupSpec{
IncludedNamespaces: []string{"shazam"},
},
Status: velerov1.BackupStatus{
Phase: velerov1.BackupPhaseFailed,
},
},
},
},
want: []*AnalyzeResult{
{
Title: "Backup application-backup",
Message: "Backup application-backup phase is Failed",
IsFail: true,
},
{
Title: "Velero Backups",
Message: "Found 1 backups",
IsPass: true,
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := analyzeBackups(tt.args.backups); !reflect.DeepEqual(got, tt.want) {
t.Errorf("analyzeBackups() = %v, want %v", got, tt.want)
}
})
}
}
func TestAnalyzeVelero_BackupStorageLocations(t *testing.T) {
type args struct {
backupStorageLocations []*velerov1.BackupStorageLocation
}
tests := []struct {
name string
args args
want []*AnalyzeResult
}{
{
name: "no backup storage locations",
args: args{
backupStorageLocations: []*velerov1.BackupStorageLocation{},
},
want: []*AnalyzeResult{
{
Title: "At least 1 Backup Storage Location configured",
Message: "No backup storage locations configured",
IsFail: true,
},
},
},
{
name: "1 backup storage location and 1 Available",
args: args{
backupStorageLocations: []*velerov1.BackupStorageLocation{
{
ObjectMeta: metav1.ObjectMeta{
Name: "default",
Namespace: "velero",
},
Spec: velerov1.BackupStorageLocationSpec{
Provider: "aws",
},
Status: velerov1.BackupStorageLocationStatus{
Phase: velerov1.BackupStorageLocationPhaseAvailable,
},
},
},
},
want: []*AnalyzeResult{
{
Title: "At least 1 Backup Storage Location configured",
Message: "Found 1 backup storage locations configured and 1 Available",
IsPass: true,
},
},
},
{
name: "1 backup storage location and 1 Unavailable",
args: args{
backupStorageLocations: []*velerov1.BackupStorageLocation{
{
ObjectMeta: metav1.ObjectMeta{
Name: "default",
Namespace: "velero",
},
Spec: velerov1.BackupStorageLocationSpec{
Provider: "aws",
},
Status: velerov1.BackupStorageLocationStatus{
Phase: velerov1.BackupStorageLocationPhaseUnavailable,
},
},
},
},
want: []*AnalyzeResult{
{
Title: "Backup Storage Location default",
Message: "Backup Storage Location [default] is in phase Unavailable",
IsWarn: true,
},
{
Title: "At least 1 Backup Storage Location configured",
Message: "Found 1 configured backup storage locations, but none are available",
IsWarn: true,
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := analyzeBackupStorageLocations(tt.args.backupStorageLocations); !reflect.DeepEqual(got, tt.want) {
t.Errorf("analyzeBackupStorageLocations() = %v, want %v", got, tt.want)
}
})
}
}
func TestAnalyzeVelero_DeleteBackupRequests(t *testing.T) {
type args struct {
deleteBackupRequests []*velerov1.DeleteBackupRequest
}
tests := []struct {
name string
args args
want []*AnalyzeResult
}{
{
name: "no backup delete requests",
args: args{
deleteBackupRequests: []*velerov1.DeleteBackupRequest{},
},
want: []*AnalyzeResult{},
},
{
name: "backup delete requests completed",
args: args{
deleteBackupRequests: []*velerov1.DeleteBackupRequest{
{
ObjectMeta: metav1.ObjectMeta{
Name: "observability-backup-20210308150016",
Namespace: "velero",
},
Spec: velerov1.DeleteBackupRequestSpec{
BackupName: "observability-backup",
},
Status: velerov1.DeleteBackupRequestStatus{
Phase: velerov1.DeleteBackupRequestPhaseProcessed,
},
},
},
},
want: []*AnalyzeResult{},
},
{
name: "backup delete requests summarize in progress",
args: args{
deleteBackupRequests: []*velerov1.DeleteBackupRequest{
{
ObjectMeta: metav1.ObjectMeta{
Name: "observability-backup-20210308150016",
Namespace: "velero",
},
Spec: velerov1.DeleteBackupRequestSpec{
BackupName: "observability-backup",
},
Status: velerov1.DeleteBackupRequestStatus{
Phase: velerov1.DeleteBackupRequestPhaseInProgress,
},
},
},
},
want: []*AnalyzeResult{
{
Title: "Delete Backup Requests summary",
Message: "Found 1 delete backup requests in progress",
IsWarn: true,
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := analyzeDeleteBackupRequests(tt.args.deleteBackupRequests); !reflect.DeepEqual(got, tt.want) {
t.Errorf("analyzeDeleteBackupRequests() = %v, want %v", got, tt.want)
}
})
}
}
func TestAnalyzeVelero_PodVolumeBackups(t *testing.T) {
type args struct {
podVolumeBackups []*velerov1.PodVolumeBackup
}
tests := []struct {
name string
args args
want []*AnalyzeResult
}{
{
name: "no pod volume backups",
args: args{
podVolumeBackups: []*velerov1.PodVolumeBackup{},
},
want: []*AnalyzeResult{},
},
{
name: "pod volume backups",
args: args{
podVolumeBackups: []*velerov1.PodVolumeBackup{
{
Spec: velerov1.PodVolumeBackupSpec{
Node: "test-node-1",
Pod: corev1.ObjectReference{
Kind: "Pod",
Name: "kotsadm-76ddbc96c4-fsr88",
Namespace: "default",
},
Volume: "backup",
BackupStorageLocation: "default",
},
Status: velerov1.PodVolumeBackupStatus{
Phase: velerov1.PodVolumeBackupPhaseCompleted,
},
},
},
},
want: []*AnalyzeResult{
{
Title: "Pod Volume Backups",
Message: "Found 1 pod volume backups",
IsPass: true,
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := analyzePodVolumeBackups(tt.args.podVolumeBackups); !reflect.DeepEqual(got, tt.want) {
t.Errorf("analyzePodVolumeBackups() = %v, want %v", got, tt.want)
}
})
}
}
func TestAnalyzeVelero_PodVolumeRestores(t *testing.T) {
type args struct {
podVolumeRestores []*velerov1.PodVolumeRestore
}
tests := []struct {
name string
args args
want []*AnalyzeResult
}{
{
name: "no pod volume restores",
args: args{
podVolumeRestores: []*velerov1.PodVolumeRestore{},
},
want: []*AnalyzeResult{},
},
{
name: "pod volume restores - no failures",
args: args{
podVolumeRestores: []*velerov1.PodVolumeRestore{
{
Spec: velerov1.PodVolumeRestoreSpec{
Pod: corev1.ObjectReference{
Kind: "Pod",
Name: "kotsadm-76ddbc96c4-fsr88",
Namespace: "default",
},
Volume: "backup",
BackupStorageLocation: "default",
},
Status: velerov1.PodVolumeRestoreStatus{
Phase: velerov1.PodVolumeRestorePhaseCompleted,
},
},
},
},
want: []*AnalyzeResult{
{
Title: "Pod Volume Restores",
Message: "Found 1 pod volume restores",
IsPass: true,
},
},
},
{
name: "pod volume restores - failures",
args: args{
podVolumeRestores: []*velerov1.PodVolumeRestore{
{
ObjectMeta: metav1.ObjectMeta{
Name: "observability-backup-20210308150016",
Namespace: "velero",
},
Spec: velerov1.PodVolumeRestoreSpec{
Pod: corev1.ObjectReference{
Kind: "Pod",
Name: "kotsadm-76ddbc96c4-fsr88",
Namespace: "default",
},
Volume: "backup",
BackupStorageLocation: "default",
},
Status: velerov1.PodVolumeRestoreStatus{
Phase: velerov1.PodVolumeRestorePhaseFailed,
},
},
},
},
want: []*AnalyzeResult{
{
Title: "Pod Volume Restore observability-backup-20210308150016",
Message: "Pod Volume Restore observability-backup-20210308150016 phase is Failed",
IsFail: true,
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := analyzePodVolumeRestores(tt.args.podVolumeRestores); !reflect.DeepEqual(got, tt.want) {
t.Errorf("analyzePodVolumeRestores() = %v, want %v", got, tt.want)
}
})
}
}
func TestAnalyzeVelero_Restores(t *testing.T) {
type args struct {
restores []*velerov1.Restore
}
tests := []struct {
name string
args args
want []*AnalyzeResult
}{
{
name: "no restores",
args: args{
restores: []*velerov1.Restore{},
},
want: []*AnalyzeResult{},
},
{
name: "restores completed",
args: args{
restores: []*velerov1.Restore{
{
Spec: velerov1.RestoreSpec{
BackupName: "observability-backup",
},
Status: velerov1.RestoreStatus{
Phase: velerov1.RestorePhaseCompleted,
},
},
},
},
want: []*AnalyzeResult{
{
Title: "Velero Restores",
Message: "Found 1 restores",
IsPass: true,
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := analyzeRestores(tt.args.restores); !reflect.DeepEqual(got, tt.want) {
t.Errorf("analyzeRestores() = %v, want %v", got, tt.want)
}
})
}
}
func TestAnalyzeVelero_Schedules(t *testing.T) {
type args struct {
schedules []*velerov1.Schedule
}
tests := []struct {
name string
args args
want []*AnalyzeResult
}{
{
name: "no schedules",
args: args{
schedules: []*velerov1.Schedule{},
},
want: []*AnalyzeResult{},
},
{
name: "schedules configured",
args: args{
schedules: []*velerov1.Schedule{
{
ObjectMeta: metav1.ObjectMeta{
Name: "daily-backup",
Namespace: "velero",
},
Spec: velerov1.ScheduleSpec{
Schedule: "0 0 * * *",
Template: velerov1.BackupSpec{
StorageLocation: "default",
IncludedNamespaces: []string{
"default",
},
IncludedResources: []string{
"*",
},
LabelSelector: &metav1.LabelSelector{
MatchLabels: map[string]string{
"app": "velero",
},
},
},
},
Status: velerov1.ScheduleStatus{
Phase: velerov1.SchedulePhaseEnabled,
LastBackup: &metav1.Time{
Time: time.Date(2023, 3, 8, 15, 0, 16, 0, time.UTC),
},
},
},
},
},
want: []*AnalyzeResult{
{
Title: "Velero Schedules",
Message: "Found 1 schedules",
IsPass: true,
},
},
},
{
name: "schedules - failures",
args: args{
schedules: []*velerov1.Schedule{
{
ObjectMeta: metav1.ObjectMeta{
Name: "daily-backup",
Namespace: "velero",
},
Spec: velerov1.ScheduleSpec{
Schedule: "0 0 * * *",
Template: velerov1.BackupSpec{
StorageLocation: "default",
IncludedNamespaces: []string{
"default",
},
IncludedResources: []string{
"*",
},
LabelSelector: &metav1.LabelSelector{
MatchLabels: map[string]string{
"app": "velero",
},
},
},
},
Status: velerov1.ScheduleStatus{
Phase: velerov1.SchedulePhaseFailedValidation,
LastBackup: &metav1.Time{
Time: time.Date(2023, 3, 8, 15, 0, 16, 0, time.UTC),
},
},
},
},
},
want: []*AnalyzeResult{
{
Title: "Schedule daily-backup",
Message: "Schedule daily-backup phase is FailedValidation",
IsFail: true,
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := analyzeSchedules(tt.args.schedules); !reflect.DeepEqual(got, tt.want) {
t.Errorf("analyzeSchedules() = %v, want %v", got, tt.want)
}
})
}
}
func TestAnalyzeVelero_VolumeSnapshotLocations(t *testing.T) {
type args struct {
volumeSnapshotLocations []*velerov1.VolumeSnapshotLocation
}
tests := []struct {
name string
args args
want []*AnalyzeResult
}{
{
name: "no volume snapshot locations",
args: args{
volumeSnapshotLocations: []*velerov1.VolumeSnapshotLocation{},
},
want: []*AnalyzeResult{},
},
{
name: "volume snapshot locations configured",
args: args{
volumeSnapshotLocations: []*velerov1.VolumeSnapshotLocation{
{
ObjectMeta: metav1.ObjectMeta{
Name: "default",
Namespace: "velero",
},
Spec: velerov1.VolumeSnapshotLocationSpec{
Provider: "aws",
Config: map[string]string{
"region": "us-east-1",
},
},
Status: velerov1.VolumeSnapshotLocationStatus{
Phase: velerov1.VolumeSnapshotLocationPhaseAvailable,
},
},
},
},
want: []*AnalyzeResult{
{
Title: "Velero Volume Snapshot Locations",
Message: "Found 1 volume snapshot locations",
IsPass: true,
},
},
},
{
name: "volume snapshot locations - failures",
args: args{
volumeSnapshotLocations: []*velerov1.VolumeSnapshotLocation{
{
ObjectMeta: metav1.ObjectMeta{
Name: "default",
Namespace: "velero",
},
Spec: velerov1.VolumeSnapshotLocationSpec{
Provider: "aws",
Config: map[string]string{
"region": "us-east-1",
},
},
Status: velerov1.VolumeSnapshotLocationStatus{
Phase: velerov1.VolumeSnapshotLocationPhaseUnavailable,
},
},
},
},
want: []*AnalyzeResult{
{
Title: "Volume Snapshot Location default",
Message: "Volume Snapshot Location default phase is Unavailable",
IsFail: true,
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := analyzeVolumeSnapshotLocations(tt.args.volumeSnapshotLocations); !reflect.DeepEqual(got, tt.want) {
t.Errorf("analyzeVolumeSnapshotLocations() = %v, want %v", got, tt.want)
}
})
}
}
func TestAnalyzeVelero_Logs(t *testing.T) {
type args struct {
logs map[string][]byte
kind string
}
tests := []struct {
name string
args args
want []*AnalyzeResult
}{
{
name: "no logs",
args: args{
logs: map[string][]byte{},
kind: "node-agent*",
},
want: []*AnalyzeResult{},
},
{
name: "logs - no errors in node-agent* pods",
args: args{
logs: map[string][]byte{
"node-agent-m6n9j": []byte("level=info msg=... backup=velero/sample-app controller=podvolumebacku"),
},
kind: "node-agent*",
},
want: []*AnalyzeResult{
{
Title: "Velero Logs analysis for kind [node-agent*]",
Message: "Found 1 log files",
IsPass: true,
},
},
},
{
name: "logs - no errors in velero* pods",
args: args{
logs: map[string][]byte{
"velero-788ff7c9dd-mslfl": []byte("level=info msg=BackupStorageLocations... controller=backup-storage-location"),
},
kind: "velero*",
},
want: []*AnalyzeResult{
{
Title: "Velero Logs analysis for kind [velero*]",
Message: "Found 1 log files",
IsPass: true,
},
},
},
{
name: "logs - errors in node-agent* pods",
args: args{
logs: map[string][]byte{
"node-agent-m6n9j": []byte("level=error msg=... backup=velero/sample-app controller=podvolumebacku"),
},
kind: "node-agent*",
},
want: []*AnalyzeResult{
{
Title: "Velero logs for pod [node-agent-m6n9j]",
Message: "Found error|panic|fatal in node-agent* pod log file(s)",
IsWarn: true,
},
{
Title: "Velero Logs analysis for kind [node-agent*]",
Message: "Found 1 log files",
IsPass: true,
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := analyzeLogs(tt.args.logs, tt.args.kind); !reflect.DeepEqual(got, tt.want) {
t.Errorf("analyzeLogs() = %v, want %v", got, tt.want)
gotJSON, _ := json.MarshalIndent(got, "", " ")
wantJSON, _ := json.MarshalIndent(tt.want, "", " ")
t.Logf("\nGot: %s\nWant: %s", gotJSON, wantJSON)
}
})
}
}
func TestAnalyzeVelero_Results(t *testing.T) {
type args struct {
results []*AnalyzeResult
}
tests := []struct {
name string
args args
want []*AnalyzeResult
}{
{
name: "no results",
args: args{
results: []*AnalyzeResult{},
},
want: []*AnalyzeResult{},
},
{
name: "results - pass",
args: args{
results: []*AnalyzeResult{
{
Title: "random Velero CRD check",
IsPass: true,
Message: "CRD status is healthy",
},
},
},
want: []*AnalyzeResult{
{
Title: "random Velero CRD check",
IsPass: true,
Message: "CRD status is healthy",
},
{
Title: "Velero Status",
IsPass: true,
Message: "Velero setup is healthy",
},
},
},
{
name: "results - fail",
args: args{
results: []*AnalyzeResult{
{
Title: "random Velero CRD check failure",
IsFail: true,
Message: "CRD status - Failed",
},
},
},
want: []*AnalyzeResult{
{
Title: "random Velero CRD check failure",
IsFail: true,
Message: "CRD status - Failed",
},
{
Title: "Velero Status",
IsWarn: true,
Message: "Velero setup is not entirely healthy",
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := aggregateResults(tt.args.results); !reflect.DeepEqual(got, tt.want) {
t.Errorf("aggregateResults() = %v, want %v", got, tt.want)
gotJSON, _ := json.MarshalIndent(got, "", " ")
wantJSON, _ := json.MarshalIndent(tt.want, "", " ")
t.Logf("\nGot: %s\nWant: %s", gotJSON, wantJSON)
}
})
}
}
+18
View File
@@ -6,6 +6,7 @@ import (
"strconv"
"github.com/pkg/errors"
util "github.com/replicatedhq/troubleshoot/internal/util"
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
iutils "github.com/replicatedhq/troubleshoot/pkg/interfaceutils"
"gopkg.in/yaml.v2"
@@ -50,6 +51,8 @@ func (a *AnalyzeYamlCompare) analyzeYamlCompare(analyzer *troubleshootv1beta2.Ya
return nil, errors.Wrap(err, "failed to parse collected data as yaml doc")
}
originalActual := actual
if analyzer.Path != "" {
actual, err = iutils.GetAtPath(actual, analyzer.Path)
if err != nil {
@@ -81,6 +84,11 @@ func (a *AnalyzeYamlCompare) analyzeYamlCompare(analyzer *troubleshootv1beta2.Ya
}
}
outcome.Fail.Message, err = util.RenderTemplate(outcome.Fail.Message, originalActual)
if err != nil {
return nil, errors.Wrap(err, "failed to render template on outcome message")
}
if when == equal {
result.IsFail = true
result.Message = outcome.Fail.Message
@@ -96,6 +104,11 @@ func (a *AnalyzeYamlCompare) analyzeYamlCompare(analyzer *troubleshootv1beta2.Ya
}
}
outcome.Warn.Message, err = util.RenderTemplate(outcome.Warn.Message, originalActual)
if err != nil {
return nil, errors.Wrap(err, "failed to render template on outcome message")
}
if when == equal {
result.IsWarn = true
result.Message = outcome.Warn.Message
@@ -111,6 +124,11 @@ func (a *AnalyzeYamlCompare) analyzeYamlCompare(analyzer *troubleshootv1beta2.Ya
}
}
outcome.Pass.Message, err = util.RenderTemplate(outcome.Pass.Message, originalActual)
if err != nil {
return nil, errors.Wrap(err, "failed to render template on outcome message")
}
if when == equal {
result.IsPass = true
result.Message = outcome.Pass.Message
+39
View File
@@ -430,6 +430,45 @@ otherstuff:
},
fileContents: []byte(``),
},
{
name: "basic comparison with outcome message templated",
analyzer: troubleshootv1beta2.YamlCompare{
Outcomes: []*troubleshootv1beta2.Outcome{
{
Pass: &troubleshootv1beta2.SingleOutcome{
Message: "Status: {{ .stuff.status }}, Info: {{ .stuff.info }}",
When: "true",
},
},
{
Fail: &troubleshootv1beta2.SingleOutcome{
Message: "Status: {{ .stuff.status }}, Info: {{ .stuff.info }}",
When: "false",
},
},
},
CollectorName: "yaml-compare",
FileName: "yaml-compare.yaml",
Value: `ready`,
Path: "stuff.status",
},
expectResult: AnalyzeResult{
IsPass: true,
IsWarn: false,
IsFail: false,
Title: "yaml-compare",
Message: "Status: ready, Info: stuff is ready",
IconKey: "kubernetes_text_analyze",
IconURI: "https://troubleshoot.sh/images/analyzer-icons/text-analyze.svg",
},
fileContents: []byte(`
stuff:
status: ready
info: stuff is ready
morestuff:
status: notready
info: morestuff is not ready`),
},
}
for _, test := range tests {
@@ -1,5 +1,4 @@
//go:build !ignore_autogenerated
// +build !ignore_autogenerated
/*
Copyright 2019 Replicated, Inc..
@@ -186,6 +186,10 @@ type CephStatusAnalyze struct {
Namespace string `json:"namespace" yaml:"namespace"`
}
type VeleroAnalyze struct {
AnalyzeMeta `json:",inline" yaml:",inline"`
}
type LonghornAnalyze struct {
AnalyzeMeta `json:",inline" yaml:",inline"`
Outcomes []*Outcome `json:"outcomes" yaml:"outcomes"`
@@ -221,6 +225,39 @@ type CertificatesAnalyze struct {
Outcomes []*Outcome `json:"outcomes" yaml:"outcomes"`
}
type GoldpingerAnalyze struct {
AnalyzeMeta `json:",inline" yaml:",inline"`
Outcomes []*Outcome `json:"outcomes,omitempty" yaml:"outcomes,omitempty"`
CollectorName string `json:"collectorName" yaml:"collectorName"`
FilePath string `json:"filePath,omitempty" yaml:"filePath,omitempty"`
}
type EventAnalyze struct {
AnalyzeMeta `json:",inline" yaml:",inline"`
CollectorName string `json:"collectorName" yaml:"collectorName"`
Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"`
Kind string `json:"kind,omitempty" yaml:"kind,omitempty"`
Reason string `json:"reason" yaml:"reason"`
RegexPattern string `json:"regex,omitempty" yaml:"regex,omitempty"`
Outcomes []*Outcome `json:"outcomes" yaml:"outcomes"`
}
type NodeMetricsAnalyze struct {
AnalyzeMeta `json:",inline" yaml:",inline"`
CollectorName string `json:"collectorName" yaml:"collectorName"`
Filters NodeMetricsAnalyzeFilters `json:"filters,omitempty" yaml:"filters,omitempty"`
Outcomes []*Outcome `json:"outcomes" yaml:"outcomes"`
}
type NodeMetricsAnalyzeFilters struct {
PVC *PVCRef `json:"pvc,omitempty" yaml:"pvc,omitempty"`
}
type PVCRef struct {
NameRegex string `json:"nameRegex,omitempty" yaml:"nameRegex,omitempty"`
Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"`
}
type Analyze struct {
ClusterVersion *ClusterVersion `json:"clusterVersion,omitempty" yaml:"clusterVersion,omitempty"`
StorageClass *StorageClass `json:"storageClass,omitempty" yaml:"storageClass,omitempty"`
@@ -245,10 +282,15 @@ type Analyze struct {
Mysql *DatabaseAnalyze `json:"mysql,omitempty" yaml:"mysql,omitempty"`
Redis *DatabaseAnalyze `json:"redis,omitempty" yaml:"redis,omitempty"`
CephStatus *CephStatusAnalyze `json:"cephStatus,omitempty" yaml:"cephStatus,omitempty"`
Velero *VeleroAnalyze `json:"velero,omitempty" yaml:"velero,omitempty"`
Longhorn *LonghornAnalyze `json:"longhorn,omitempty" yaml:"longhorn,omitempty"`
RegistryImages *RegistryImagesAnalyze `json:"registryImages,omitempty" yaml:"registryImages,omitempty"`
WeaveReport *WeaveReportAnalyze `json:"weaveReport,omitempty" yaml:"weaveReport,omitempty"`
Sysctl *SysctlAnalyze `json:"sysctl,omitempty" yaml:"sysctl,omitempty"`
ClusterResource *ClusterResource `json:"clusterResource,omitempty" yaml:"clusterResource,omitempty"`
Certificates *CertificatesAnalyze `json:"certificates,omitempty" yaml:"certificates,omitempty"`
Goldpinger *GoldpingerAnalyze `json:"goldpinger,omitempty" yaml:"goldpinger,omitempty"`
Event *EventAnalyze `json:"event,omitempty" yaml:"event,omitempty"`
NodeMetrics *NodeMetricsAnalyze `json:"nodeMetrics,omitempty" yaml:"nodeMetrics,omitempty"`
HTTP *HTTPAnalyze `json:"http,omitempty" yaml:"http,omitempty"`
}
@@ -24,6 +24,7 @@ import (
type AnalyzerSpec struct {
Analyzers []*Analyze `json:"analyzers,omitempty"`
HostAnalyzers []*HostAnalyze `json:"hostAnalyzers,omitempty" yaml:"hostAnalyzers,omitempty"`
Uri string `json:"uri,omitempty" yaml:"uri,omitempty"`
}
// AnalyzerStatus defines the observed state of Analyzer
@@ -44,6 +44,12 @@ type CustomMetrics struct {
MetricRequests []MetricRequest `json:"metricRequests,omitempty" yaml:"metricRequests,omitempty"`
}
type NodeMetrics struct {
CollectorMeta `json:",inline" yaml:",inline"`
NodeNames []string `json:"nodeNames,omitempty" yaml:"nodeNames,omitempty"`
Selector []string `json:"selector,omitempty" yaml:"selector,omitempty"`
}
type Secret struct {
CollectorMeta `json:",inline" yaml:",inline"`
Name string `json:"name,omitempty" yaml:"name,omitempty"`
@@ -105,6 +111,16 @@ type RunPod struct {
Timeout string `json:"timeout,omitempty" yaml:"timeout,omitempty"`
ImagePullSecret *ImagePullSecrets `json:"imagePullSecret,omitempty" yaml:"imagePullSecret,omitempty"`
PodSpec corev1.PodSpec `json:"podSpec,omitempty" yaml:"podSpec,omitempty"`
Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"`
}
type RunDaemonSet struct {
CollectorMeta `json:",inline" yaml:",inline"`
Name string `json:"name,omitempty" yaml:"name,omitempty"`
Namespace string `json:"namespace" yaml:"namespace"`
Timeout string `json:"timeout,omitempty" yaml:"timeout,omitempty"`
ImagePullSecret *ImagePullSecrets `json:"imagePullSecret,omitempty" yaml:"imagePullSecret,omitempty"`
PodSpec corev1.PodSpec `json:"podSpec,omitempty" yaml:"podSpec,omitempty"`
}
type ImagePullSecrets struct {
@@ -257,6 +273,35 @@ type Helm struct {
CollectorMeta `json:",inline" yaml:",inline"`
Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"`
ReleaseName string `json:"releaseName,omitempty" yaml:"releaseName,omitempty"`
CollectValues bool `json:"collectValues,omitempty" yaml:"collectValues,omitempty"`
}
type Goldpinger struct {
CollectorMeta `json:",inline" yaml:",inline"`
Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"`
PodLaunchOptions *PodLaunchOptions `json:"podLaunchOptions,omitempty" yaml:"podLaunchOptions,omitempty"`
}
type PodLaunchOptions struct {
Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"`
Image string `json:"image,omitempty" yaml:"image,omitempty"`
ImagePullSecret *ImagePullSecrets `json:"imagePullSecret,omitempty" yaml:"imagePullSecret,omitempty"`
ServiceAccountName string `json:"serviceAccountName,omitempty" yaml:"serviceAccountName,omitempty"`
}
type Sonobuoy struct {
CollectorMeta `json:",inline" yaml:",inline"`
Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"`
}
type DNS struct {
CollectorMeta `json:",inline" yaml:",inline"`
Timeout string `json:"timeout,omitempty" yaml:"timeout,omitempty"`
}
type Etcd struct {
CollectorMeta `json:",inline" yaml:",inline"`
Image string `json:"image" yaml:"image"`
}
type Collect struct {
@@ -268,6 +313,7 @@ type Collect struct {
Logs *Logs `json:"logs,omitempty" yaml:"logs,omitempty"`
Run *Run `json:"run,omitempty" yaml:"run,omitempty"`
RunPod *RunPod `json:"runPod,omitempty" yaml:"runPod,omitempty"`
RunDaemonSet *RunDaemonSet `json:"runDaemonSet,omitempty" yaml:"runDaemonSet,omitempty"`
Exec *Exec `json:"exec,omitempty" yaml:"exec,omitempty"`
Data *Data `json:"data,omitempty" yaml:"data,omitempty"`
Copy *Copy `json:"copy,omitempty" yaml:"copy,omitempty"`
@@ -284,6 +330,11 @@ type Collect struct {
Sysctl *Sysctl `json:"sysctl,omitempty" yaml:"sysctl,omitempty"`
Certificates *Certificates `json:"certificates,omitempty" yaml:"certificates,omitempty"`
Helm *Helm `json:"helm,omitempty" yaml:"helm,omitempty"`
Goldpinger *Goldpinger `json:"goldpinger,omitempty" yaml:"goldpinger,omitempty"`
Sonobuoy *Sonobuoy `json:"sonobuoy,omitempty" yaml:"sonobuoy,omitempty"`
NodeMetrics *NodeMetrics `json:"nodeMetrics,omitempty" yaml:"nodeMetrics,omitempty"`
DNS *DNS `json:"dns,omitempty" yaml:"dns,omitempty"`
Etcd *Etcd `json:"etcd,omitempty" yaml:"etcd,omitempty"`
}
func (c *Collect) AccessReviewSpecs(overrideNS string) []authorizationv1.SelfSubjectAccessReviewSpec {
@@ -417,6 +468,19 @@ func (c *Collect) AccessReviewSpecs(overrideNS string) []authorizationv1.SelfSub
},
NonResourceAttributes: nil,
})
} else if c.RunDaemonSet != nil {
result = append(result, authorizationv1.SelfSubjectAccessReviewSpec{
ResourceAttributes: &authorizationv1.ResourceAttributes{
Namespace: pickNamespaceOrDefault(c.RunDaemonSet.Namespace, overrideNS),
Verb: "create",
Group: "",
Version: "",
Resource: "pods",
Subresource: "",
Name: "",
},
NonResourceAttributes: nil,
})
} else if c.Exec != nil {
result = append(result, authorizationv1.SelfSubjectAccessReviewSpec{
ResourceAttributes: &authorizationv1.ResourceAttributes{
@@ -527,6 +591,10 @@ func (c *Collect) GetName() string {
collector = "run-pod"
name = c.RunPod.CollectorName
}
if c.RunDaemonSet != nil {
collector = "run-daemonset"
name = c.RunDaemonSet.CollectorName
}
if c.Exec != nil {
collector = "exec"
name = c.Exec.CollectorName
@@ -35,6 +35,7 @@ type AfterCollection struct {
type CollectorSpec struct {
Collectors []*Collect `json:"collectors,omitempty" yaml:"collectors,omitempty"`
AfterCollection []*AfterCollection `json:"afterCollection,omitempty" yaml:"afterCollection,omitempty"`
Uri string `json:"uri,omitempty" yaml:"uri,omitempty"`
}
// CollectorStatus defines the observed state of Collector
@@ -24,6 +24,7 @@ import (
type HostCollectorSpec struct {
Collectors []*HostCollect `json:"collectors,omitempty" yaml:"collectors,omitempty"`
Analyzers []*HostAnalyze `json:"analyzers,omitempty" yaml:"analyzers,omitempty"`
Uri string `json:"uri,omitempty" yaml:"uri,omitempty"`
}
// HostCollectorStatus defines the observed state of HostCollector
@@ -122,6 +122,13 @@ type HostOSAnalyze struct {
Outcomes []*Outcome `json:"outcomes" yaml:"outcomes"`
}
type KernelConfigsAnalyze struct {
AnalyzeMeta `json:",inline" yaml:",inline"`
CollectorName string `json:"collectorName,omitempty" yaml:"collectorName,omitempty"`
SelectedConfigs []string `json:"selectedConfigs" yaml:"selectedConfigs"`
Outcomes []*Outcome `json:"outcomes" yaml:"outcomes"`
}
type HostAnalyze struct {
CPU *CPUAnalyze `json:"cpu,omitempty" yaml:"cpu,omitempty"`
TCPLoadBalancer *TCPLoadBalancerAnalyze `json:"tcpLoadBalancer,omitempty" yaml:"tcpLoadBalancer,omitempty"`
@@ -144,4 +151,6 @@ type HostAnalyze struct {
HostServices *HostServicesAnalyze `json:"hostServices,omitempty" yaml:"hostServices,omitempty"`
HostOS *HostOSAnalyze `json:"hostOS,omitempty" yaml:"hostOS,omitempty"`
TextAnalyze *TextAnalyze `json:"textAnalyze,omitempty" yaml:"textAnalyze,omitempty"`
KernelConfigs *KernelConfigsAnalyze `json:"kernelConfigs,omitempty" yaml:"kernelConfigs,omitempty"`
JsonCompare *JsonCompare `json:"jsonCompare,omitempty" yaml:"jsonCompare,omitempty"`
}
@@ -76,6 +76,11 @@ type HostCopy struct {
Path string `json:"path" yaml:"path"`
}
type HostCGroups struct {
HostCollectorMeta `json:",inline" yaml:",inline"`
MountPoint string `json:"mountPoint,omitempty" yaml:"mountPoint,omitempty"`
}
type HostTime struct {
HostCollectorMeta `json:",inline" yaml:",inline"`
}
@@ -180,8 +185,32 @@ type HostServices struct {
type HostRun struct {
HostCollectorMeta `json:",inline" yaml:",inline"`
Command string `json:"command"`
Args []string `json:"args"`
Command string `json:"command"`
Args []string `json:"args"`
OutputDir string `json:"outputDir,omitempty" yaml:"outputDir,omitempty"`
Input map[string]string `json:"input,omitempty" yaml:"input,omitempty"`
Env []string `json:"env,omitempty" yaml:"env,omitempty"`
InheritEnvs []string `json:"inheritEnvs,omitempty" yaml:"inheritEnvs,omitempty"`
IgnoreParentEnvs bool `json:"ignoreParentEnvs,omitempty" yaml:"ignoreParentEnvs,omitempty"`
Timeout string `json:"timeout,omitempty" yaml:"timeout,omitempty"`
}
type HostKernelConfigs struct {
HostCollectorMeta `json:",inline" yaml:",inline"`
}
type HostJournald struct {
HostCollectorMeta `json:",inline" yaml:",inline"`
System bool `json:"system,omitempty" yaml:"system,omitempty"`
Dmesg bool `json:"dmesg,omitempty" yaml:"dmesg,omitempty"`
Units []string `json:"units,omitempty" yaml:"units,omitempty"`
Since string `json:"since,omitempty" yaml:"since,omitempty"`
Until string `json:"until,omitempty" yaml:"until,omitempty"`
Output string `json:"output,omitempty" yaml:"output,omitempty"`
Lines int `json:"lines,omitempty" yaml:"lines,omitempty"`
Reverse bool `json:"reverse,omitempty" yaml:"reverse,omitempty"`
Utc bool `json:"utc,omitempty" yaml:"utc,omitempty"`
Timeout string `json:"timeout,omitempty" yaml:"timeout,omitempty"`
}
type HostCollect struct {
@@ -208,8 +237,13 @@ type HostCollect struct {
HostOS *HostOS `json:"hostOS,omitempty" yaml:"hostOS,omitempty"`
HostRun *HostRun `json:"run,omitempty" yaml:"run,omitempty"`
HostCopy *HostCopy `json:"copy,omitempty" yaml:"copy,omitempty"`
HostKernelConfigs *HostKernelConfigs `json:"kernelConfigs,omitempty" yaml:"kernelConfigs,omitempty"`
HostJournald *HostJournald `json:"journald,omitempty" yaml:"journald,omitempty"`
HostCGroups *HostCGroups `json:"cgroups,omitempty" yaml:"cgroups,omitempty"`
}
// GetName gets the name of the collector
// Deprecated: This function is not used anywhere and should be removed. Do not use it.
func (c *HostCollect) GetName() string {
// TODO: Is this used anywhere? Should we just remove it?
var collector string
@@ -25,6 +25,7 @@ type HostPreflightSpec struct {
Collectors []*HostCollect `json:"collectors,omitempty" yaml:"collectors,omitempty"`
RemoteCollectors []*RemoteCollect `json:"remoteCollectors,omitempty" yaml:"remoteCollectors,omitempty"`
Analyzers []*HostAnalyze `json:"analyzers,omitempty" yaml:"analyzers,omitempty"`
Uri string `json:"uri,omitempty" yaml:"uri,omitempty"`
}
// HostPreflightStatus defines the observed state of HostPreflight
@@ -26,6 +26,7 @@ type PreflightSpec struct {
Collectors []*Collect `json:"collectors,omitempty" yaml:"collectors,omitempty"`
RemoteCollectors []*RemoteCollect `json:"remoteCollectors,omitempty" yaml:"remoteCollectors,omitempty"`
Analyzers []*Analyze `json:"analyzers,omitempty" yaml:"analyzers,omitempty"`
Uri string `json:"uri,omitempty" yaml:"uri,omitempty"`
}
// PreflightStatus defines the observed state of Preflight
@@ -23,6 +23,7 @@ import (
// RedactorSpec defines the desired state of Redactor
type RedactorSpec struct {
Redactors []*Redact `json:"redactors,omitempty"`
Uri string `json:"uri,omitempty" yaml:"uri,omitempty"`
}
// RedactorStatus defines the observed state of Redactor
@@ -25,6 +25,7 @@ type RemoteCollectorSpec struct {
Collectors []*RemoteCollect `json:"collectors,omitempty" yaml:"collectors,omitempty"`
AfterCollection []*AfterCollection `json:"afterCollection,omitempty" yaml:"afterCollection,omitempty"`
NodeSelector map[string]string `json:"nodeSelector,omitempty" yaml:"nodeSelector,omitempty"`
Uri string `json:"uri,omitempty" yaml:"uri,omitempty"`
}
// +genclient
@@ -1,5 +1,4 @@
//go:build !ignore_autogenerated
// +build !ignore_autogenerated
/*
Copyright 2019 Replicated, Inc..
@@ -169,6 +168,11 @@ func (in *Analyze) DeepCopyInto(out *Analyze) {
*out = new(CephStatusAnalyze)
(*in).DeepCopyInto(*out)
}
if in.Velero != nil {
in, out := &in.Velero, &out.Velero
*out = new(VeleroAnalyze)
(*in).DeepCopyInto(*out)
}
if in.Longhorn != nil {
in, out := &in.Longhorn, &out.Longhorn
*out = new(LonghornAnalyze)
@@ -199,6 +203,26 @@ func (in *Analyze) DeepCopyInto(out *Analyze) {
*out = new(CertificatesAnalyze)
(*in).DeepCopyInto(*out)
}
if in.Goldpinger != nil {
in, out := &in.Goldpinger, &out.Goldpinger
*out = new(GoldpingerAnalyze)
(*in).DeepCopyInto(*out)
}
if in.Event != nil {
in, out := &in.Event, &out.Event
*out = new(EventAnalyze)
(*in).DeepCopyInto(*out)
}
if in.NodeMetrics != nil {
in, out := &in.NodeMetrics, &out.NodeMetrics
*out = new(NodeMetricsAnalyze)
(*in).DeepCopyInto(*out)
}
if in.HTTP != nil {
in, out := &in.HTTP, &out.HTTP
*out = new(HTTPAnalyze)
(*in).DeepCopyInto(*out)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Analyze.
@@ -807,6 +831,11 @@ func (in *Collect) DeepCopyInto(out *Collect) {
*out = new(RunPod)
(*in).DeepCopyInto(*out)
}
if in.RunDaemonSet != nil {
in, out := &in.RunDaemonSet, &out.RunDaemonSet
*out = new(RunDaemonSet)
(*in).DeepCopyInto(*out)
}
if in.Exec != nil {
in, out := &in.Exec, &out.Exec
*out = new(Exec)
@@ -887,6 +916,31 @@ func (in *Collect) DeepCopyInto(out *Collect) {
*out = new(Helm)
(*in).DeepCopyInto(*out)
}
if in.Goldpinger != nil {
in, out := &in.Goldpinger, &out.Goldpinger
*out = new(Goldpinger)
(*in).DeepCopyInto(*out)
}
if in.Sonobuoy != nil {
in, out := &in.Sonobuoy, &out.Sonobuoy
*out = new(Sonobuoy)
(*in).DeepCopyInto(*out)
}
if in.NodeMetrics != nil {
in, out := &in.NodeMetrics, &out.NodeMetrics
*out = new(NodeMetrics)
(*in).DeepCopyInto(*out)
}
if in.DNS != nil {
in, out := &in.DNS, &out.DNS
*out = new(DNS)
(*in).DeepCopyInto(*out)
}
if in.Etcd != nil {
in, out := &in.Etcd, &out.Etcd
*out = new(Etcd)
(*in).DeepCopyInto(*out)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Collect.
@@ -1216,6 +1270,22 @@ func (in *CustomResourceDefinition) DeepCopy() *CustomResourceDefinition {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *DNS) DeepCopyInto(out *DNS) {
*out = *in
in.CollectorMeta.DeepCopyInto(&out.CollectorMeta)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DNS.
func (in *DNS) DeepCopy() *DNS {
if in == nil {
return nil
}
out := new(DNS)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Data) DeepCopyInto(out *Data) {
*out = *in
@@ -1387,6 +1457,49 @@ func (in *Distribution) DeepCopy() *Distribution {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Etcd) DeepCopyInto(out *Etcd) {
*out = *in
in.CollectorMeta.DeepCopyInto(&out.CollectorMeta)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Etcd.
func (in *Etcd) DeepCopy() *Etcd {
if in == nil {
return nil
}
out := new(Etcd)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *EventAnalyze) DeepCopyInto(out *EventAnalyze) {
*out = *in
in.AnalyzeMeta.DeepCopyInto(&out.AnalyzeMeta)
if in.Outcomes != nil {
in, out := &in.Outcomes, &out.Outcomes
*out = make([]*Outcome, len(*in))
for i := range *in {
if (*in)[i] != nil {
in, out := &(*in)[i], &(*out)[i]
*out = new(Outcome)
(*in).DeepCopyInto(*out)
}
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EventAnalyze.
func (in *EventAnalyze) DeepCopy() *EventAnalyze {
if in == nil {
return nil
}
out := new(EventAnalyze)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Exec) DeepCopyInto(out *Exec) {
*out = *in
@@ -1503,6 +1616,54 @@ func (in *Get) DeepCopy() *Get {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Goldpinger) DeepCopyInto(out *Goldpinger) {
*out = *in
in.CollectorMeta.DeepCopyInto(&out.CollectorMeta)
if in.PodLaunchOptions != nil {
in, out := &in.PodLaunchOptions, &out.PodLaunchOptions
*out = new(PodLaunchOptions)
(*in).DeepCopyInto(*out)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Goldpinger.
func (in *Goldpinger) DeepCopy() *Goldpinger {
if in == nil {
return nil
}
out := new(Goldpinger)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *GoldpingerAnalyze) DeepCopyInto(out *GoldpingerAnalyze) {
*out = *in
in.AnalyzeMeta.DeepCopyInto(&out.AnalyzeMeta)
if in.Outcomes != nil {
in, out := &in.Outcomes, &out.Outcomes
*out = make([]*Outcome, len(*in))
for i := range *in {
if (*in)[i] != nil {
in, out := &(*in)[i], &(*out)[i]
*out = new(Outcome)
(*in).DeepCopyInto(*out)
}
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GoldpingerAnalyze.
func (in *GoldpingerAnalyze) DeepCopy() *GoldpingerAnalyze {
if in == nil {
return nil
}
out := new(GoldpingerAnalyze)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HTTP) DeepCopyInto(out *HTTP) {
*out = *in
@@ -1728,6 +1889,16 @@ func (in *HostAnalyze) DeepCopyInto(out *HostAnalyze) {
*out = new(TextAnalyze)
(*in).DeepCopyInto(*out)
}
if in.KernelConfigs != nil {
in, out := &in.KernelConfigs, &out.KernelConfigs
*out = new(KernelConfigsAnalyze)
(*in).DeepCopyInto(*out)
}
if in.JsonCompare != nil {
in, out := &in.JsonCompare, &out.JsonCompare
*out = new(JsonCompare)
(*in).DeepCopyInto(*out)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HostAnalyze.
@@ -1756,6 +1927,22 @@ func (in *HostBlockDevices) DeepCopy() *HostBlockDevices {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HostCGroups) DeepCopyInto(out *HostCGroups) {
*out = *in
in.HostCollectorMeta.DeepCopyInto(&out.HostCollectorMeta)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HostCGroups.
func (in *HostCGroups) DeepCopy() *HostCGroups {
if in == nil {
return nil
}
out := new(HostCGroups)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HostCertificatesCollection) DeepCopyInto(out *HostCertificatesCollection) {
*out = *in
@@ -1922,6 +2109,21 @@ func (in *HostCollect) DeepCopyInto(out *HostCollect) {
*out = new(HostCopy)
(*in).DeepCopyInto(*out)
}
if in.HostKernelConfigs != nil {
in, out := &in.HostKernelConfigs, &out.HostKernelConfigs
*out = new(HostKernelConfigs)
(*in).DeepCopyInto(*out)
}
if in.HostJournald != nil {
in, out := &in.HostJournald, &out.HostJournald
*out = new(HostJournald)
(*in).DeepCopyInto(*out)
}
if in.HostCGroups != nil {
in, out := &in.HostCGroups, &out.HostCGroups
*out = new(HostCGroups)
(*in).DeepCopyInto(*out)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HostCollect.
@@ -2112,6 +2314,43 @@ func (in *HostHTTP) DeepCopy() *HostHTTP {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HostJournald) DeepCopyInto(out *HostJournald) {
*out = *in
in.HostCollectorMeta.DeepCopyInto(&out.HostCollectorMeta)
if in.Units != nil {
in, out := &in.Units, &out.Units
*out = make([]string, len(*in))
copy(*out, *in)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HostJournald.
func (in *HostJournald) DeepCopy() *HostJournald {
if in == nil {
return nil
}
out := new(HostJournald)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HostKernelConfigs) DeepCopyInto(out *HostKernelConfigs) {
*out = *in
in.HostCollectorMeta.DeepCopyInto(&out.HostCollectorMeta)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HostKernelConfigs.
func (in *HostKernelConfigs) DeepCopy() *HostKernelConfigs {
if in == nil {
return nil
}
out := new(HostKernelConfigs)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HostKernelModules) DeepCopyInto(out *HostKernelModules) {
*out = *in
@@ -2302,6 +2541,23 @@ func (in *HostRun) DeepCopyInto(out *HostRun) {
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.Input != nil {
in, out := &in.Input, &out.Input
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
if in.Env != nil {
in, out := &in.Env, &out.Env
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.InheritEnvs != nil {
in, out := &in.InheritEnvs, &out.InheritEnvs
*out = make([]string, len(*in))
copy(*out, *in)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HostRun.
@@ -2672,6 +2928,38 @@ func (in *JsonCompare) DeepCopy() *JsonCompare {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *KernelConfigsAnalyze) DeepCopyInto(out *KernelConfigsAnalyze) {
*out = *in
in.AnalyzeMeta.DeepCopyInto(&out.AnalyzeMeta)
if in.SelectedConfigs != nil {
in, out := &in.SelectedConfigs, &out.SelectedConfigs
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.Outcomes != nil {
in, out := &in.Outcomes, &out.Outcomes
*out = make([]*Outcome, len(*in))
for i := range *in {
if (*in)[i] != nil {
in, out := &(*in)[i], &(*out)[i]
*out = new(Outcome)
(*in).DeepCopyInto(*out)
}
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KernelConfigsAnalyze.
func (in *KernelConfigsAnalyze) DeepCopy() *KernelConfigsAnalyze {
if in == nil {
return nil
}
out := new(KernelConfigsAnalyze)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *KernelModulesAnalyze) DeepCopyInto(out *KernelModulesAnalyze) {
*out = *in
@@ -2863,6 +3151,80 @@ func (in *MetricRequest) DeepCopy() *MetricRequest {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *NodeMetrics) DeepCopyInto(out *NodeMetrics) {
*out = *in
in.CollectorMeta.DeepCopyInto(&out.CollectorMeta)
if in.NodeNames != nil {
in, out := &in.NodeNames, &out.NodeNames
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.Selector != nil {
in, out := &in.Selector, &out.Selector
*out = make([]string, len(*in))
copy(*out, *in)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeMetrics.
func (in *NodeMetrics) DeepCopy() *NodeMetrics {
if in == nil {
return nil
}
out := new(NodeMetrics)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *NodeMetricsAnalyze) DeepCopyInto(out *NodeMetricsAnalyze) {
*out = *in
in.AnalyzeMeta.DeepCopyInto(&out.AnalyzeMeta)
in.Filters.DeepCopyInto(&out.Filters)
if in.Outcomes != nil {
in, out := &in.Outcomes, &out.Outcomes
*out = make([]*Outcome, len(*in))
for i := range *in {
if (*in)[i] != nil {
in, out := &(*in)[i], &(*out)[i]
*out = new(Outcome)
(*in).DeepCopyInto(*out)
}
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeMetricsAnalyze.
func (in *NodeMetricsAnalyze) DeepCopy() *NodeMetricsAnalyze {
if in == nil {
return nil
}
out := new(NodeMetricsAnalyze)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *NodeMetricsAnalyzeFilters) DeepCopyInto(out *NodeMetricsAnalyzeFilters) {
*out = *in
if in.PVC != nil {
in, out := &in.PVC, &out.PVC
*out = new(PVCRef)
**out = **in
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeMetricsAnalyzeFilters.
func (in *NodeMetricsAnalyzeFilters) DeepCopy() *NodeMetricsAnalyzeFilters {
if in == nil {
return nil
}
out := new(NodeMetricsAnalyzeFilters)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *NodeResourceFilters) DeepCopyInto(out *NodeResourceFilters) {
*out = *in
@@ -2967,6 +3329,41 @@ func (in *Outcome) DeepCopy() *Outcome {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *PVCRef) DeepCopyInto(out *PVCRef) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PVCRef.
func (in *PVCRef) DeepCopy() *PVCRef {
if in == nil {
return nil
}
out := new(PVCRef)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *PodLaunchOptions) DeepCopyInto(out *PodLaunchOptions) {
*out = *in
if in.ImagePullSecret != nil {
in, out := &in.ImagePullSecret, &out.ImagePullSecret
*out = new(ImagePullSecrets)
(*in).DeepCopyInto(*out)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodLaunchOptions.
func (in *PodLaunchOptions) DeepCopy() *PodLaunchOptions {
if in == nil {
return nil
}
out := new(PodLaunchOptions)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Post) DeepCopyInto(out *Post) {
*out = *in
@@ -3978,6 +4375,28 @@ func (in *Run) DeepCopy() *Run {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *RunDaemonSet) DeepCopyInto(out *RunDaemonSet) {
*out = *in
in.CollectorMeta.DeepCopyInto(&out.CollectorMeta)
if in.ImagePullSecret != nil {
in, out := &in.ImagePullSecret, &out.ImagePullSecret
*out = new(ImagePullSecrets)
(*in).DeepCopyInto(*out)
}
in.PodSpec.DeepCopyInto(&out.PodSpec)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RunDaemonSet.
func (in *RunDaemonSet) DeepCopy() *RunDaemonSet {
if in == nil {
return nil
}
out := new(RunDaemonSet)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *RunPod) DeepCopyInto(out *RunPod) {
*out = *in
@@ -3988,6 +4407,13 @@ func (in *RunPod) DeepCopyInto(out *RunPod) {
(*in).DeepCopyInto(*out)
}
in.PodSpec.DeepCopyInto(&out.PodSpec)
if in.Annotations != nil {
in, out := &in.Annotations, &out.Annotations
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RunPod.
@@ -4036,6 +4462,22 @@ func (in *SingleOutcome) DeepCopy() *SingleOutcome {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Sonobuoy) DeepCopyInto(out *Sonobuoy) {
*out = *in
in.CollectorMeta.DeepCopyInto(&out.CollectorMeta)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Sonobuoy.
func (in *Sonobuoy) DeepCopy() *Sonobuoy {
if in == nil {
return nil
}
out := new(Sonobuoy)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *StatefulsetStatus) DeepCopyInto(out *StatefulsetStatus) {
*out = *in
@@ -4654,6 +5096,22 @@ func (in *UDPPortStatusAnalyze) DeepCopy() *UDPPortStatusAnalyze {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *VeleroAnalyze) DeepCopyInto(out *VeleroAnalyze) {
*out = *in
in.AnalyzeMeta.DeepCopyInto(&out.AnalyzeMeta)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VeleroAnalyze.
func (in *VeleroAnalyze) DeepCopy() *VeleroAnalyze {
if in == nil {
return nil
}
out := new(VeleroAnalyze)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *WeaveReportAnalyze) DeepCopyInto(out *WeaveReportAnalyze) {
*out = *in
+33 -11
View File
@@ -19,6 +19,7 @@ package troubleshootclientset
import (
"fmt"
"net/http"
troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1"
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2"
@@ -33,8 +34,7 @@ type Interface interface {
TroubleshootV1beta2() troubleshootv1beta2.TroubleshootV1beta2Interface
}
// Clientset contains the clients for groups. Each group has exactly one
// version included in a Clientset.
// Clientset contains the clients for groups.
type Clientset struct {
*discovery.DiscoveryClient
troubleshootV1beta1 *troubleshootv1beta1.TroubleshootV1beta1Client
@@ -62,26 +62,49 @@ func (c *Clientset) Discovery() discovery.DiscoveryInterface {
// NewForConfig creates a new Clientset for the given config.
// If config's RateLimiter is not set and QPS and Burst are acceptable,
// NewForConfig will generate a rate-limiter in configShallowCopy.
// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient),
// where httpClient was generated with rest.HTTPClientFor(c).
func NewForConfig(c *rest.Config) (*Clientset, error) {
configShallowCopy := *c
if configShallowCopy.UserAgent == "" {
configShallowCopy.UserAgent = rest.DefaultKubernetesUserAgent()
}
// share the transport between all clients
httpClient, err := rest.HTTPClientFor(&configShallowCopy)
if err != nil {
return nil, err
}
return NewForConfigAndClient(&configShallowCopy, httpClient)
}
// NewForConfigAndClient creates a new Clientset for the given config and http client.
// Note the http client provided takes precedence over the configured transport values.
// If config's RateLimiter is not set and QPS and Burst are acceptable,
// NewForConfigAndClient will generate a rate-limiter in configShallowCopy.
func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset, error) {
configShallowCopy := *c
if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 {
if configShallowCopy.Burst <= 0 {
return nil, fmt.Errorf("burst is required to be greater than 0 when RateLimiter is not set and QPS is set to greater than 0")
}
configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst)
}
var cs Clientset
var err error
cs.troubleshootV1beta1, err = troubleshootv1beta1.NewForConfig(&configShallowCopy)
cs.troubleshootV1beta1, err = troubleshootv1beta1.NewForConfigAndClient(&configShallowCopy, httpClient)
if err != nil {
return nil, err
}
cs.troubleshootV1beta2, err = troubleshootv1beta2.NewForConfig(&configShallowCopy)
cs.troubleshootV1beta2, err = troubleshootv1beta2.NewForConfigAndClient(&configShallowCopy, httpClient)
if err != nil {
return nil, err
}
cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfig(&configShallowCopy)
cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfigAndClient(&configShallowCopy, httpClient)
if err != nil {
return nil, err
}
@@ -91,12 +114,11 @@ func NewForConfig(c *rest.Config) (*Clientset, error) {
// NewForConfigOrDie creates a new Clientset for the given config and
// panics if there is an error in the config.
func NewForConfigOrDie(c *rest.Config) *Clientset {
var cs Clientset
cs.troubleshootV1beta1 = troubleshootv1beta1.NewForConfigOrDie(c)
cs.troubleshootV1beta2 = troubleshootv1beta2.NewForConfigOrDie(c)
cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c)
return &cs
cs, err := NewForConfig(c)
if err != nil {
panic(err)
}
return cs
}
// New creates a new Clientset for the given RESTClient.
@@ -23,7 +23,6 @@ import (
v1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
labels "k8s.io/apimachinery/pkg/labels"
schema "k8s.io/apimachinery/pkg/runtime/schema"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
testing "k8s.io/client-go/testing"
@@ -35,9 +34,9 @@ type FakeAnalyzers struct {
ns string
}
var analyzersResource = schema.GroupVersionResource{Group: "troubleshoot.replicated.com", Version: "v1beta1", Resource: "analyzers"}
var analyzersResource = v1beta1.SchemeGroupVersion.WithResource("analyzers")
var analyzersKind = schema.GroupVersionKind{Group: "troubleshoot.replicated.com", Version: "v1beta1", Kind: "Analyzer"}
var analyzersKind = v1beta1.SchemeGroupVersion.WithKind("Analyzer")
// Get takes name of the analyzer, and returns the corresponding analyzer object, and an error if there is any.
func (c *FakeAnalyzers) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.Analyzer, err error) {
@@ -116,7 +115,7 @@ func (c *FakeAnalyzers) UpdateStatus(ctx context.Context, analyzer *v1beta1.Anal
// Delete takes name of the analyzer and deletes it. Returns an error if one occurs.
func (c *FakeAnalyzers) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
_, err := c.Fake.
Invokes(testing.NewDeleteAction(analyzersResource, c.ns, name), &v1beta1.Analyzer{})
Invokes(testing.NewDeleteActionWithOptions(analyzersResource, c.ns, name, opts), &v1beta1.Analyzer{})
return err
}
@@ -23,7 +23,6 @@ import (
v1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
labels "k8s.io/apimachinery/pkg/labels"
schema "k8s.io/apimachinery/pkg/runtime/schema"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
testing "k8s.io/client-go/testing"
@@ -35,9 +34,9 @@ type FakeCollectors struct {
ns string
}
var collectorsResource = schema.GroupVersionResource{Group: "troubleshoot.replicated.com", Version: "v1beta1", Resource: "collectors"}
var collectorsResource = v1beta1.SchemeGroupVersion.WithResource("collectors")
var collectorsKind = schema.GroupVersionKind{Group: "troubleshoot.replicated.com", Version: "v1beta1", Kind: "Collector"}
var collectorsKind = v1beta1.SchemeGroupVersion.WithKind("Collector")
// Get takes name of the collector, and returns the corresponding collector object, and an error if there is any.
func (c *FakeCollectors) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.Collector, err error) {
@@ -116,7 +115,7 @@ func (c *FakeCollectors) UpdateStatus(ctx context.Context, collector *v1beta1.Co
// Delete takes name of the collector and deletes it. Returns an error if one occurs.
func (c *FakeCollectors) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
_, err := c.Fake.
Invokes(testing.NewDeleteAction(collectorsResource, c.ns, name), &v1beta1.Collector{})
Invokes(testing.NewDeleteActionWithOptions(collectorsResource, c.ns, name, opts), &v1beta1.Collector{})
return err
}
@@ -23,7 +23,6 @@ import (
v1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
labels "k8s.io/apimachinery/pkg/labels"
schema "k8s.io/apimachinery/pkg/runtime/schema"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
testing "k8s.io/client-go/testing"
@@ -35,9 +34,9 @@ type FakePreflights struct {
ns string
}
var preflightsResource = schema.GroupVersionResource{Group: "troubleshoot.replicated.com", Version: "v1beta1", Resource: "preflights"}
var preflightsResource = v1beta1.SchemeGroupVersion.WithResource("preflights")
var preflightsKind = schema.GroupVersionKind{Group: "troubleshoot.replicated.com", Version: "v1beta1", Kind: "Preflight"}
var preflightsKind = v1beta1.SchemeGroupVersion.WithKind("Preflight")
// Get takes name of the preflight, and returns the corresponding preflight object, and an error if there is any.
func (c *FakePreflights) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.Preflight, err error) {
@@ -116,7 +115,7 @@ func (c *FakePreflights) UpdateStatus(ctx context.Context, preflight *v1beta1.Pr
// Delete takes name of the preflight and deletes it. Returns an error if one occurs.
func (c *FakePreflights) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
_, err := c.Fake.
Invokes(testing.NewDeleteAction(preflightsResource, c.ns, name), &v1beta1.Preflight{})
Invokes(testing.NewDeleteActionWithOptions(preflightsResource, c.ns, name, opts), &v1beta1.Preflight{})
return err
}
@@ -23,7 +23,6 @@ import (
v1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
labels "k8s.io/apimachinery/pkg/labels"
schema "k8s.io/apimachinery/pkg/runtime/schema"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
testing "k8s.io/client-go/testing"
@@ -35,9 +34,9 @@ type FakeRedactors struct {
ns string
}
var redactorsResource = schema.GroupVersionResource{Group: "troubleshoot.replicated.com", Version: "v1beta1", Resource: "redactors"}
var redactorsResource = v1beta1.SchemeGroupVersion.WithResource("redactors")
var redactorsKind = schema.GroupVersionKind{Group: "troubleshoot.replicated.com", Version: "v1beta1", Kind: "Redactor"}
var redactorsKind = v1beta1.SchemeGroupVersion.WithKind("Redactor")
// Get takes name of the redactor, and returns the corresponding redactor object, and an error if there is any.
func (c *FakeRedactors) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.Redactor, err error) {
@@ -116,7 +115,7 @@ func (c *FakeRedactors) UpdateStatus(ctx context.Context, redactor *v1beta1.Reda
// Delete takes name of the redactor and deletes it. Returns an error if one occurs.
func (c *FakeRedactors) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
_, err := c.Fake.
Invokes(testing.NewDeleteAction(redactorsResource, c.ns, name), &v1beta1.Redactor{})
Invokes(testing.NewDeleteActionWithOptions(redactorsResource, c.ns, name, opts), &v1beta1.Redactor{})
return err
}
@@ -23,7 +23,6 @@ import (
v1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
labels "k8s.io/apimachinery/pkg/labels"
schema "k8s.io/apimachinery/pkg/runtime/schema"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
testing "k8s.io/client-go/testing"
@@ -35,9 +34,9 @@ type FakeSupportBundles struct {
ns string
}
var supportbundlesResource = schema.GroupVersionResource{Group: "troubleshoot.replicated.com", Version: "v1beta1", Resource: "supportbundles"}
var supportbundlesResource = v1beta1.SchemeGroupVersion.WithResource("supportbundles")
var supportbundlesKind = schema.GroupVersionKind{Group: "troubleshoot.replicated.com", Version: "v1beta1", Kind: "SupportBundle"}
var supportbundlesKind = v1beta1.SchemeGroupVersion.WithKind("SupportBundle")
// Get takes name of the supportBundle, and returns the corresponding supportBundle object, and an error if there is any.
func (c *FakeSupportBundles) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.SupportBundle, err error) {
@@ -116,7 +115,7 @@ func (c *FakeSupportBundles) UpdateStatus(ctx context.Context, supportBundle *v1
// Delete takes name of the supportBundle and deletes it. Returns an error if one occurs.
func (c *FakeSupportBundles) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
_, err := c.Fake.
Invokes(testing.NewDeleteAction(supportbundlesResource, c.ns, name), &v1beta1.SupportBundle{})
Invokes(testing.NewDeleteActionWithOptions(supportbundlesResource, c.ns, name, opts), &v1beta1.SupportBundle{})
return err
}
@@ -18,6 +18,8 @@ limitations under the License.
package v1beta1
import (
"net/http"
v1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
"github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/scheme"
rest "k8s.io/client-go/rest"
@@ -58,12 +60,28 @@ func (c *TroubleshootV1beta1Client) SupportBundles(namespace string) SupportBund
}
// NewForConfig creates a new TroubleshootV1beta1Client for the given config.
// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient),
// where httpClient was generated with rest.HTTPClientFor(c).
func NewForConfig(c *rest.Config) (*TroubleshootV1beta1Client, error) {
config := *c
if err := setConfigDefaults(&config); err != nil {
return nil, err
}
client, err := rest.RESTClientFor(&config)
httpClient, err := rest.HTTPClientFor(&config)
if err != nil {
return nil, err
}
return NewForConfigAndClient(&config, httpClient)
}
// NewForConfigAndClient creates a new TroubleshootV1beta1Client for the given config and http client.
// Note the http client provided takes precedence over the configured transport values.
func NewForConfigAndClient(c *rest.Config, h *http.Client) (*TroubleshootV1beta1Client, error) {
config := *c
if err := setConfigDefaults(&config); err != nil {
return nil, err
}
client, err := rest.RESTClientForConfigAndClient(&config, h)
if err != nil {
return nil, err
}

Some files were not shown because too many files have changed in this diff Show More