Compare commits

...
293 Commits
Author SHA1 Message Date
Noah Campbell 3cd2b9a87b doesnt harcode apiVersion line when looking and figures out which apiVersion to give if none is there 2025-10-13 13:20:01 -05:00
Noah Campbell 898a59fe40 improved --fix capabilities 2025-10-07 16:58:18 -07:00
Noah Campbell e71bf87cc2 added lint subcommand 2025-10-07 16:19:01 -07:00
Noah Campbell 774fd8d935 handle empty structural_compare rules 2025-10-07 09:08:02 -07:00
Noah Campbell 1d4315ced6 simplify comparison to detect code regressions only 2025-10-07 08:58:03 -07:00
Noah Campbell b6b2bf8483 handle node-specific files and multiple report arguments 2025-10-07 08:47:05 -07:00
Noah Campbell ac9a4c9c5b create test/output directory 2025-10-07 08:34:35 -07:00
Noah Campbell c532928cd2 Update regression-test.yaml 2025-10-07 08:21:52 -07:00
Noah Campbell 4b04098689 Update regression-test.yaml 2025-10-07 08:16:38 -07:00
Noah Campbell b3369c2b3e Update regression-test.yaml 2025-10-07 08:13:18 -07:00
Noah Campbell fbfd6c99fe Add regression test suite to github actions 2025-10-07 08:10:32 -07:00
Noah Campbell 12f8bc3daa Improved error handling for support bundles and redactors for windows (#1878)
* improved error handling and window locking

* Delete all-windows-collectors.yaml

* addressing bugbot concerns

* Update host_tcpportstatus.go

* Update redact.go
2025-10-06 14:32:29 -07:00
Noah Campbell b4e3ed278a Removes silent failing (#1877)
* preserves stdout and stderr from collectors

* Delete eliminate-silent-failures.md

* Update host_kernel_modules_test.go

* added error logs when a collector fails to start

* Update host_filesystem_performance_linux.go

* fixed error saving logic inconsistency

* Update collect.go
2025-10-04 15:14:10 -07:00
Benjamin Yang c67775c1a0 feat: clean tokenization system implementation (#1874)
Core tokenization functionality with minimal file changes:

 Core Features:
- Intelligent tokenization engine (tokenizer.go)
- Context-aware secret classification (PASSWORD, APIKEY, DATABASE, etc.)
- Cross-file correlation with deterministic HMAC-SHA256 tokens
- Optional encrypted mapping for token→original value resolution

 Integration:
- CLI flags: --tokenize, --redaction-map, --encrypt-redaction-map
- Updated all redactor types: literal, single-line, multi-line, YAML
- Support bundle integration with auto-upload compatibility
- Backward compatibility: preserves ***HIDDEN*** when disabled

 Production Ready:
- Only 11 essential files (vs 31 in original PR)
- No excessive test files or documentation
- Clean build, all functionality verified
- Maintains existing redaction behavior by default

Token format: ***TOKEN_<TYPE>_<HASH>*** (e.g., ***TOKEN_PASSWORD_A1B2C3***)
2025-09-30 15:04:23 -05:00
83e6cffe5f Cron job clean (#1862)
* created roadmap and yaml claude agent

* Update roadmap.md

* chore(deps): bump sigstore/cosign-installer from 3.9.2 to 3.10.0 (#1857)

Bumps [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer) from 3.9.2 to 3.10.0.
- [Release notes](https://github.com/sigstore/cosign-installer/releases)
- [Commits](https://github.com/sigstore/cosign-installer/compare/v3.9.2...v3.10.0)

---
updated-dependencies:
- dependency-name: sigstore/cosign-installer
  dependency-version: 3.10.0
  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>

* chore(deps): bump the security group with 2 updates (#1858)

Bumps the security group with 2 updates: [github.com/vmware-tanzu/velero](https://github.com/vmware-tanzu/velero) and [helm.sh/helm/v3](https://github.com/helm/helm).


Updates `github.com/vmware-tanzu/velero` from 1.16.2 to 1.17.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.16.2...v1.17.0)

Updates `helm.sh/helm/v3` from 3.18.6 to 3.19.0
- [Release notes](https://github.com/helm/helm/releases)
- [Commits](https://github.com/helm/helm/compare/v3.18.6...v3.19.0)

---
updated-dependencies:
- dependency-name: github.com/vmware-tanzu/velero
  dependency-version: 1.17.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: helm.sh/helm/v3
  dependency-version: 3.19.0
  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>

* chore(deps): bump helm.sh/helm/v3 from 3.18.6 to 3.19.0 in /examples/sdk/helm-template in the security group (#1859)

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.18.6 to 3.19.0
- [Release notes](https://github.com/helm/helm/releases)
- [Commits](https://github.com/helm/helm/compare/v3.18.6...v3.19.0)

---
updated-dependencies:
- dependency-name: helm.sh/helm/v3
  dependency-version: 3.19.0
  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>

* Add cron job support bundle scheduler

Complete implementation with K8s integration:
- pkg/schedule/job.go: Job management and persistence
- pkg/schedule/daemon.go: Real-time scheduler daemon
- pkg/schedule/cli.go: CLI commands (create, list, delete, daemon)
- pkg/schedule/schedule_test.go: Comprehensive unit tests
- cmd/troubleshoot/cli/root.go: CLI integration

* fixing bugbot

* Fix all bugbot errors: auto-update stability, job cooldown timing, and daemon execution

* Deleting Agent

* removed unused flags

* fixing auto-upload

* fixing markdown files

* namespace not required flag for auto collectors to work

* loosened cron job validation

* writes logs to logfile

* fix: resolve autoFromEnv variable scoping issue for CI

- Ensure autoFromEnv variable and its usage are in correct scope
- Fix build errors: declared and not used / undefined variable
- All functionality preserved and tested locally
- Force add to override gitignore

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Noah Campbell <noah.edward.campbell@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-30 14:11:15 -05:00
Benjamin Yang 84dc8157b9 Auto-Collect (#1867)
* Fix auto-collector missing files issue

- Add KOTS-aware detection for diagnostic files
- Replace silent RBAC filtering with user warnings
- Enhance error file collection for troubleshooting
- Achieve parity with traditional support bundles

Resolves issue where auto-collector was missing:
- KOTS diagnostic files (now 4 vs 3)
- ConfigMaps (now 6 vs 6)
- Maintains superior log collection (24 vs 0)

Final result: [SUCCESS] comprehensive collection achieved

* fixing bugbog

* fix: resolve production readiness issues in auto-collect branch

1. Fix diff test expectations (lines should have newlines for difflib consistency)
2. Fix preflight tests to use existing v1beta3 example file
3. Fix autodiscovery test context parameter (function signature update)

Resolves TestReadLinesFromReader and preflight v1beta3 test failures

* fix: resolve autodiscovery tests and cursor bot image matching issues

1. Fix cursor bot image matching bug in isKotsadmImage:
   - Replace flawed prefix matching with proper image component detection
   - Handle private registries correctly (registry.company.com/kotsadm/kotsadm:v1.0.0)
   - Prevent false positives with proper delimiter checking
   - Add helper functions: containsImageComponent, splitImagePath, removeTagAndDigest

2. Fix autodiscovery test failures:
   - Add TestMode flag to DiscoveryOptions to control KOTS diagnostic collection
   - Tests use TestMode=true to get only foundational collectors (no KOTS diagnostics)
   - Preserves production behavior while enabling clean testing

Resolves failing TestDiscoverer_DiscoverFoundational tests and cursor bot issues
2025-09-30 12:26:10 -05:00
Benjamin YangandNoah Campbell a8fb5210f4 Advanced analysis clean (#1868)
* created roadmap and yaml claude agent

* Update roadmap.md

* feat: Clean advanced analysis implementation - core agents, engine, artifacts

* Remove unrelated files - keep only advanced analysis implementation

* fix: Fix goroutine leak in hosted agent rate limiter

- Added stop channel and stopped flag to RateLimiter struct
- Modified replenishTokens to listen for stop signal and exit cleanly
- Added Stop() method to gracefully shutdown rate limiter
- Added Stop() method to HostedAgent to cleanup rate limiter on shutdown

Fixes cursor bot issue: Rate Limiter Goroutine Leak

* fix: Fix analyzer config and model validation bugs

Bug 1: Analyzer Config Missing File Path
- Added filePath to DeploymentStatus analyzer config in convertAnalyzerToSpec
- Sets namespace-specific path (cluster-resources/deployments/{namespace}.json)
- Falls back to generic path (cluster-resources/deployments.json) if no namespace
- Fixes LocalAgent.analyzeDeploymentStatus backward compatibility

Bug 2: HealthCheck Fails Model Validation
- Changed Ollama model validation from prefix match to exact match
- Prevents false positives where llama2:13b would match request for llama2:7b
- Ensures agent only reports healthy when exact model is available

Both fixes address cursor bot reported issues and maintain backward compatibility.

* fixing lint errors

* fixing lint errors

* adding CLI flags

* fix: resolve linting errors for CI

- Remove unnecessary nil check in host_kernel_configs.go (len() for nil slices is zero)
- Remove unnecessary fmt.Sprintf() calls in ceph.go for static strings
- Apply go fmt formatting fixes

Fixes failing lint CI check

* fix: resolve CI failures in build-test workflow and Ollama tests

1. Fix GitHub Actions workflow logic error:
   - Replace problematic contains() expression with explicit job result checks
   - Properly handle failure and cancelled states for each job
   - Prevents false positive failures in success summary job

2. Fix Ollama agent parseLLMResponse panics:
   - Add proper error handling for malformed JSON in LLM responses
   - Return error when JSON is found but invalid (instead of silent fallback)
   - Add error when no meaningful content can be parsed from response
   - Prevents nil pointer dereference in test assertions

Fixes failing build-test/success and build-test/test CI checks

* fix: resolve all CI failures and cursor bot issues

1. Fix disable-ollama flag logic bug:
   - Remove disable-ollama from advanced analysis trigger condition
   - Prevents unintended advanced analysis mode when no agents registered
   - Allows proper fallback to legacy analysis

2. Fix diff test consistency:
   - Update test expectations to match function behavior (lines with newlines)
   - Ensures consistency between streaming and non-streaming diff paths

3. Fix Ollama agent error handling:
   - Add proper error return for malformed JSON in LLM responses
   - Add meaningful content validation for markdown parsing
   - Prevents nil pointer panics in test assertions

4. Fix analysis engine mock agent:
   - Mock agent now processes and returns results for all provided analyzers
   - Fixes test expectation mismatch (expected 8 results, got 1)

Resolves all failing CI checks: lint, test, and success workflow logic

---------

Co-authored-by: Noah Campbell <noah.edward.campbell@gmail.com>
2025-09-30 11:44:46 -05:00
Marc Campbell d3af4edd31 bump example 2025-09-29 21:34:01 -07:00
Marc Campbell b9dc00cc6c removing risc 2025-09-29 21:19:11 -07:00
Marc Campbell 8990c4b06e some more goreleaser/homebrew stuffs 2025-09-29 21:11:03 -07:00
Marc Campbell e03fa0a046 publish to directory: 2025-09-29 21:00:21 -07:00
Marc Campbell 758d454434 prerelease auto and more 2025-09-29 20:48:28 -07:00
Marc Campbell f0d0eda060 larger 2025-09-29 19:57:57 -07:00
Marc Campbell 4eea31d916 goreleaser 2025-09-29 19:55:14 -07:00
Marc Campbell cfea35e7c0 fix syntax 2025-09-29 19:47:50 -07:00
Marc Campbell 630aa631ee fix syntax 2025-09-29 19:44:50 -07:00
Marc Campbell b61728a11f dropping goreleaser 2025-09-29 19:20:17 -07:00
Marc Campbell 252f9650c9 larger runner for release 2025-09-29 19:02:49 -07:00
Marc Campbell 857a028585 add debug logging 2025-09-29 18:54:17 -07:00
Marc Campbell 6e8704d6f1 remove this check 2025-09-29 18:37:28 -07:00
Marc Campbell c8c246a809 remove collect binary and risc binary 2025-09-29 18:36:36 -07:00
Marc Campbell a41958c173 bump goreleaser to v2 2025-09-29 18:13:11 -07:00
Benjamin YangandNoah Campbell 17518349ff Fix/exec textanalyze path clean (#1865)
* created roadmap and yaml claude agent

* Update roadmap.md

* Fix textAnalyze analyzer to auto-match exec collector nested paths

- Auto-detect exec output files (*-stdout.txt, *-stderr.txt, *-errors.json)
- Convert simple filenames to wildcard patterns automatically
- Preserve existing wildcard patterns
- Fixes 'No matching file' errors for exec + textAnalyze workflows

---------

Co-authored-by: Noah Campbell <noah.edward.campbell@gmail.com>
2025-09-29 17:49:54 -07:00
Benjamin Yang 266647ef2f Fixing testing errors (#1871)
fix: resolve failing unit tests and diff consistency in v1beta3

- Fix readLinesFromReader to return lines WITH newlines (like difflib.SplitLines)
- Update test expectations to match correct function behavior with newlines
- This ensures consistency between streaming and non-streaming diff paths
- Fix timeout test by changing from 10ms to 500ms to eliminate flaky failures

Fixes TestReadLinesFromReader and Test_loadSupportBundleSpecsFromURIs_TimeoutError
Resolves diff output inconsistency between code paths
2025-09-29 17:48:51 -07:00
Marc Campbell 3062dd8d5c adding brew (#1872) 2025-09-29 15:01:22 -07:00
Marc Campbell 91db72b484 removing coverage reporting 2025-09-29 14:36:51 -07:00
Marc Campbell 5f0835f7d0 add a v1beta3 fixture 2025-09-29 11:02:51 -07:00
Marc Campbell 9af9845fb9 removing unused examples 2025-09-29 10:50:00 -07:00
Marc Campbell 007ef32e77 fmt: 2025-09-29 10:43:51 -07:00
Marc Campbell d9904d9632 update ci for v1beta3 (#1870) 2025-09-29 10:40:04 -07:00
Marc Campbell 074fee81f7 V1beta3 cleanup (#1869)
* moving some files around

* more cleanup

* removing more unused
2025-09-29 10:10:41 -07:00
Noah Campbell 7bd7eca528 does not auto update for package managers (#1850) 2025-09-18 12:56:12 -05:00
Noah Campbell b1830ff515 moved v1beta3 examples to proper directory 2025-09-17 17:38:26 -05:00
Noah Campbell 885819ea9a Auto support bundle upload (#1860)
* basic auto uploading support bundles

* added upload command

* added default vendor endpoint

* added auth system from replicated cli

* fixed case sensitivity issue in YAML parsing

* support bundle uploads for end customers

* app slug flag and detection without licenseID
2025-09-17 12:59:41 -05:00
Noah Campbell 20b0c5ed06 fixed gitignore issue 2025-09-17 11:02:53 -05:00
Noah Campbell 71067edb41 Updated yaml spec (#1863)
* v1beta3 spec can be read by preflight

* added test files for ease of testing

* v1beta3 renderer fixes
2025-09-17 10:38:11 -05:00
Noah Campbell d0584a4d4d Updated yaml spec (#1851)
* v1beta3 spec can be read by preflight

* added test files for ease of testing

* updated v1beta3 guide doc and added tests

* fixed not removing tmp files from v1beta3 processing

* created v1beta2 to v1beta3 converter
2025-09-16 15:43:46 -05:00
Noah Campbell acc1aad843 Preflight docs and template subcommands (#1847)
* Added docs and template subcommands with test files

* uses helm templating preflight yaml files

* merge doc requirements for multiple inputs

* Helm aware rendering and markdown output

* v1beta3 yaml structure better mirrors beta2

* Update sample-preflight-templated.yaml

* Added docs and template subcommands with test files

* uses helm templating preflight yaml files

* merge doc requirements for multiple inputs

* Helm aware rendering and markdown output

* v1beta3 yaml structure better mirrors beta2

* Update sample-preflight-templated.yaml

* Added/updated documentation on subcommands

* Update docs.go

* commit to trigger actions
2025-09-16 14:12:09 -05:00
Noah Campbell 8027e273e4 Support bundle diff (#1855)
implemented support bundle diff command
2025-09-15 13:20:35 -05:00
Marc Campbell 3b9d280a95 resetting make targets and github workflows to support v1beta3 releas… (#1853)
* resetting make targets and github workflows to support v1beta3 release later

* removing generate

* remove

* removing

* removing
2025-09-15 09:15:53 -07:00
Benjamin YangandBenjamin Yang 74811c669b Auto-collectors: foundational discovery, image metadata, CLI integrat… (#1845)
* Auto-collectors: foundational discovery, image metadata, CLI integration; reset PRD markers

* Address PR review feedback

- Implement missing namespace exclude patterns functionality
- Fix image facts collector to use empty Data field instead of static string
- Correct APIVersion to use troubleshoot.sh/v1beta2 consistently

* Fix bug bot issues: API parsing, EOF error, and API group corrections

- Fix RBAC API parsing errors in rbac_checker.go (getAPIGroup/getAPIVersion functions)
- Fix FakeReader EOF error to use standard io.EOF instead of custom error
- Fix incorrect API group from troubleshoot.sh to troubleshoot.replicated.com in run.go

These changes address the issues identified by the bug bot and ensure proper
interface compliance and consistent API group usage.

* Fix multiple bug bot issues

- Fix RBAC API parsing errors in rbac_checker.go (getAPIGroup/getAPIVersion functions)
- Fix FakeReader EOF error to use standard io.EOF instead of custom error
- Fix incorrect API group from troubleshoot.sh to troubleshoot.replicated.com in run.go
- Fix image facts collector Data field to contain structured JSON instead of static strings

These changes address all issues identified by the bug bot and ensure proper
interface compliance, consistent API usage, and meaningful data fields.

* Update auto_discovery.go

* Fix TODO comments in Auto-collector section

Fixed 3 of 4 TODOs as requested in PR review:

1. pkg/collect/images/registry_client.go (line 46):
   - Implement custom CA certificate loading
   - Add x509 import and certificate parsing logic
   - Enables image collection from private registries with custom CAs

2. cmd/troubleshoot/cli/diff.go (line 209):
   - Implement bundle file count functionality
   - Add tar/gzip imports and getFileCountFromBundle() function
   - Properly counts files in support bundle archives (.gz/.tgz)

3. cmd/troubleshoot/cli/run.go (line 338):
   - Replace TODO with clarifying comment about RemoteCollectors usage
   - Confirmed RemoteCollectors are still actively used in preflights

The 4th TODO (diff.go line 196) is left as-is since it's explicitly marked
as Phase 4 future work (Support Bundle Differencing implementation).

Addresses PR review feedback about unimplemented TODO comments.

---------

Co-authored-by: Benjamin Yang <benjaminyang@Benjamins-MacBook-Pro.local>
2025-09-12 13:44:26 -06:00
Noah Campbell a1d1a12c1a Auto updater (#1849)
* added auto updater

* updated docs

* commit to trigger actions
2025-09-12 12:30:57 -06:00
Noah Campbell 050dc8499f Change workflow branch from 'main' to 'v1beta3' 2025-09-12 11:08:16 -05:00
Ethan Mosbaugh f352396e2e fix(collect): add context timeout to registry collector (#1846)
* fix(collect): add context timeout to registry collector

* f

* f
2025-09-10 11:47:58 -07:00
dependabot[bot]andlnx01 50ada4abdf chore(deps): bump the security group across 1 directory with 9 updates (#1844)
Bumps the security group with 6 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [k8s.io/api](https://github.com/kubernetes/api) | `0.34.0` | `0.34.1` |
| [k8s.io/apiextensions-apiserver](https://github.com/kubernetes/apiextensions-apiserver) | `0.34.0` | `0.34.1` |
| [k8s.io/cli-runtime](https://github.com/kubernetes/cli-runtime) | `0.34.0` | `0.34.1` |
| [k8s.io/kubernetes](https://github.com/kubernetes/kubernetes) | `1.34.0` | `1.34.1` |
| [k8s.io/kubelet](https://github.com/kubernetes/kubelet) | `0.34.0` | `0.34.1` |
| [k8s.io/metrics](https://github.com/kubernetes/metrics) | `0.34.0` | `0.34.1` |



Updates `k8s.io/api` from 0.34.0 to 0.34.1
- [Commits](https://github.com/kubernetes/api/compare/v0.34.0...v0.34.1)

Updates `k8s.io/apiextensions-apiserver` from 0.34.0 to 0.34.1
- [Release notes](https://github.com/kubernetes/apiextensions-apiserver/releases)
- [Commits](https://github.com/kubernetes/apiextensions-apiserver/compare/v0.34.0...v0.34.1)

Updates `k8s.io/apimachinery` from 0.34.0 to 0.34.1
- [Commits](https://github.com/kubernetes/apimachinery/compare/v0.34.0...v0.34.1)

Updates `k8s.io/apiserver` from 0.34.0 to 0.34.1
- [Commits](https://github.com/kubernetes/apiserver/compare/v0.34.0...v0.34.1)

Updates `k8s.io/cli-runtime` from 0.34.0 to 0.34.1
- [Commits](https://github.com/kubernetes/cli-runtime/compare/v0.34.0...v0.34.1)

Updates `k8s.io/client-go` from 0.34.0 to 0.34.1
- [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kubernetes/client-go/compare/v0.34.0...v0.34.1)

Updates `k8s.io/kubernetes` from 1.34.0 to 1.34.1
- [Release notes](https://github.com/kubernetes/kubernetes/releases)
- [Commits](https://github.com/kubernetes/kubernetes/compare/v1.34.0...v1.34.1)

Updates `k8s.io/kubelet` from 0.34.0 to 0.34.1
- [Commits](https://github.com/kubernetes/kubelet/compare/v0.34.0...v0.34.1)

Updates `k8s.io/metrics` from 0.34.0 to 0.34.1
- [Commits](https://github.com/kubernetes/metrics/compare/v0.34.0...v0.34.1)

---
updated-dependencies:
- dependency-name: k8s.io/api
  dependency-version: 0.34.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/apiextensions-apiserver
  dependency-version: 0.34.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/apimachinery
  dependency-version: 0.34.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/apiserver
  dependency-version: 0.34.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/cli-runtime
  dependency-version: 0.34.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/client-go
  dependency-version: 0.34.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/kubernetes
  dependency-version: 1.34.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/kubelet
  dependency-version: 0.34.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/metrics
  dependency-version: 0.34.1
  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>
2025-09-10 09:23:53 -07:00
João Antunes 5cd98acdc1 fix(cluster_resources): pod disruption budgets for policy v1 not being collected (#1843)
* fix(cluster_resources): pod disruption budgets for policy v1 not being collected

* fix: e2e test

* fix: now actually fix the e2e test
2025-09-10 16:30:06 +01:00
Ethan Mosbaughandlnx01 45e3e3a922 chore(deps): bump the security group across 1 directory with 13 updates (#1842)
* chore(deps): bump the security group across 1 directory with 13 updates

Bumps the security group with 11 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [github.com/casbin/govaluate](https://github.com/casbin/govaluate) | `1.9.0` | `1.10.0` |
| [github.com/containers/image/v5](https://github.com/containers/image) | `5.36.1` | `5.36.2` |
| [github.com/hashicorp/go-getter](https://github.com/hashicorp/go-getter) | `1.7.9` | `1.8.0` |
| [github.com/jackc/pgx/v5](https://github.com/jackc/pgx) | `5.7.5` | `5.7.6` |
| [github.com/spf13/pflag](https://github.com/spf13/pflag) | `1.0.9` | `1.0.10` |
| [github.com/spf13/viper](https://github.com/spf13/viper) | `1.20.1` | `1.21.0` |
| [golang.org/x/mod](https://github.com/golang/mod) | `0.27.0` | `0.28.0` |
| [golang.org/x/sync](https://github.com/golang/sync) | `0.16.0` | `0.17.0` |
| [k8s.io/kubernetes](https://github.com/kubernetes/kubernetes) | `1.33.4` | `1.34.0` |
| [sigs.k8s.io/controller-runtime](https://github.com/kubernetes-sigs/controller-runtime) | `0.22.0` | `0.22.1` |
| [golang.org/x/net](https://github.com/golang/net) | `0.43.0` | `0.44.0` |



Updates `github.com/casbin/govaluate` from 1.9.0 to 1.10.0
- [Release notes](https://github.com/casbin/govaluate/releases)
- [Changelog](https://github.com/casbin/govaluate/blob/master/.releaserc.json)
- [Commits](https://github.com/casbin/govaluate/compare/v1.9.0...v1.10.0)

Updates `github.com/containers/image/v5` from 5.36.1 to 5.36.2
- [Release notes](https://github.com/containers/image/releases)
- [Commits](https://github.com/containers/image/compare/v5.36.1...v5.36.2)

Updates `github.com/hashicorp/go-getter` from 1.7.9 to 1.8.0
- [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.9...v1.8.0)

Updates `github.com/jackc/pgx/v5` from 5.7.5 to 5.7.6
- [Changelog](https://github.com/jackc/pgx/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jackc/pgx/compare/v5.7.5...v5.7.6)

Updates `github.com/spf13/pflag` from 1.0.9 to 1.0.10
- [Release notes](https://github.com/spf13/pflag/releases)
- [Commits](https://github.com/spf13/pflag/compare/v1.0.9...v1.0.10)

Updates `github.com/spf13/viper` from 1.20.1 to 1.21.0
- [Release notes](https://github.com/spf13/viper/releases)
- [Commits](https://github.com/spf13/viper/compare/v1.20.1...v1.21.0)

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

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

Updates `k8s.io/kubernetes` from 1.33.4 to 1.34.0
- [Release notes](https://github.com/kubernetes/kubernetes/releases)
- [Commits](https://github.com/kubernetes/kubernetes/compare/v1.33.4...v1.34.0)

Updates `sigs.k8s.io/controller-runtime` from 0.22.0 to 0.22.1
- [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.22.0...v0.22.1)

Updates `golang.org/x/net` from 0.43.0 to 0.44.0
- [Commits](https://github.com/golang/net/compare/v0.43.0...v0.44.0)

Updates `golang.org/x/sys` from 0.35.0 to 0.36.0
- [Commits](https://github.com/golang/sys/compare/v0.35.0...v0.36.0)

Updates `golang.org/x/text` from 0.28.0 to 0.29.0
- [Release notes](https://github.com/golang/text/releases)
- [Commits](https://github.com/golang/text/compare/v0.28.0...v0.29.0)

---
updated-dependencies:
- dependency-name: github.com/casbin/govaluate
  dependency-version: 1.10.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: github.com/containers/image/v5
  dependency-version: 5.36.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: github.com/hashicorp/go-getter
  dependency-version: 1.8.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: github.com/jackc/pgx/v5
  dependency-version: 5.7.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: github.com/spf13/pflag
  dependency-version: 1.0.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: github.com/spf13/viper
  dependency-version: 1.21.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: golang.org/x/mod
  dependency-version: 0.28.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: golang.org/x/sync
  dependency-version: 0.17.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: k8s.io/kubernetes
  dependency-version: 1.34.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: sigs.k8s.io/controller-runtime
  dependency-version: 0.22.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: golang.org/x/net
  dependency-version: 0.44.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: golang.org/x/sys
  dependency-version: 0.36.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: golang.org/x/text
  dependency-version: 0.29.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
...

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

* fix

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-10 07:34:31 -07:00
Ash dd48aadf7f Allow filtering node resources on taint. (#1840)
* allow filtering node resources on taint
2025-09-09 14:33:51 +01:00
dependabot[bot]andlnx01 c5dc2a19f7 chore(deps): bump actions/setup-go from 5 to 6 (#1839)
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 5 to 6.
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/setup-go
  dependency-version: '6'
  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>
2025-09-08 20:25:34 -04:00
Noah Campbell dffc66a824 Update Claude agents and commands (#1836)
Added:
- agents/codebase-pattern-finder.md
- agents/architecture-patterns.md
- agents/web-search-researcher.md
- agents/project-builder.md
- agents/go-developer.md
- agents/proposal-needed.md
- agents/ci-developer.md
- agents/proposals-locator.md
- agents/proposal-writer.md
- agents/shortcut.md
- agents/researcher.md
- agents/testing.md
- agents/proposals-analyzer.md
- agents/codebase-analyzer.md
- agents/codebase-locator.md
- agents/frontend-developer.md
- commands/implement.md
- commands/proposal.md

Source: github.com/replicatedhq/.claude
2025-09-08 11:46:30 -05:00
Ethan Mosbaughandlnx01 6e62251904 chore(deps): bump the security group with 16 updates (#1835)
* chore(deps): bump the security group with 16 updates

Bumps the security group with 16 updates:

| Package | From | To |
| --- | --- | --- |
| [github.com/shirou/gopsutil/v4](https://github.com/shirou/gopsutil) | `4.25.7` | `4.25.8` |
| [github.com/spf13/cobra](https://github.com/spf13/cobra) | `1.9.1` | `1.10.1` |
| [github.com/spf13/pflag](https://github.com/spf13/pflag) | `1.0.7` | `1.0.9` |
| [github.com/stretchr/testify](https://github.com/stretchr/testify) | `1.11.0` | `1.11.1` |
| [go.opentelemetry.io/otel](https://github.com/open-telemetry/opentelemetry-go) | `1.37.0` | `1.38.0` |
| [go.opentelemetry.io/otel/sdk](https://github.com/open-telemetry/opentelemetry-go) | `1.37.0` | `1.38.0` |
| [k8s.io/api](https://github.com/kubernetes/api) | `0.33.4` | `0.34.0` |
| [k8s.io/apiextensions-apiserver](https://github.com/kubernetes/apiextensions-apiserver) | `0.33.4` | `0.34.0` |
| [k8s.io/apimachinery](https://github.com/kubernetes/apimachinery) | `0.33.4` | `0.34.0` |
| [k8s.io/apiserver](https://github.com/kubernetes/apiserver) | `0.33.4` | `0.34.0` |
| [k8s.io/cli-runtime](https://github.com/kubernetes/cli-runtime) | `0.33.4` | `0.34.0` |
| [k8s.io/client-go](https://github.com/kubernetes/client-go) | `0.33.4` | `0.34.0` |
| [sigs.k8s.io/controller-runtime](https://github.com/kubernetes-sigs/controller-runtime) | `0.21.0` | `0.22.0` |
| [k8s.io/kubelet](https://github.com/kubernetes/kubelet) | `0.33.4` | `0.34.0` |
| [k8s.io/metrics](https://github.com/kubernetes/metrics) | `0.33.4` | `0.34.0` |
| [k8s.io/utils](https://github.com/kubernetes/utils) | `0.0.0-20241104100929-3ea5e8cea738` | `0.0.0-20250604170112-4c0f3b243397` |


Updates `github.com/shirou/gopsutil/v4` from 4.25.7 to 4.25.8
- [Release notes](https://github.com/shirou/gopsutil/releases)
- [Commits](https://github.com/shirou/gopsutil/compare/v4.25.7...v4.25.8)

Updates `github.com/spf13/cobra` from 1.9.1 to 1.10.1
- [Release notes](https://github.com/spf13/cobra/releases)
- [Commits](https://github.com/spf13/cobra/compare/v1.9.1...v1.10.1)

Updates `github.com/spf13/pflag` from 1.0.7 to 1.0.9
- [Release notes](https://github.com/spf13/pflag/releases)
- [Commits](https://github.com/spf13/pflag/compare/v1.0.7...v1.0.9)

Updates `github.com/stretchr/testify` from 1.11.0 to 1.11.1
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.11.0...v1.11.1)

Updates `go.opentelemetry.io/otel` from 1.37.0 to 1.38.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.37.0...v1.38.0)

Updates `go.opentelemetry.io/otel/sdk` from 1.37.0 to 1.38.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.37.0...v1.38.0)

Updates `k8s.io/api` from 0.33.4 to 0.34.0
- [Commits](https://github.com/kubernetes/api/compare/v0.33.4...v0.34.0)

Updates `k8s.io/apiextensions-apiserver` from 0.33.4 to 0.34.0
- [Release notes](https://github.com/kubernetes/apiextensions-apiserver/releases)
- [Commits](https://github.com/kubernetes/apiextensions-apiserver/compare/v0.33.4...v0.34.0)

Updates `k8s.io/apimachinery` from 0.33.4 to 0.34.0
- [Commits](https://github.com/kubernetes/apimachinery/compare/v0.33.4...v0.34.0)

Updates `k8s.io/apiserver` from 0.33.4 to 0.34.0
- [Commits](https://github.com/kubernetes/apiserver/compare/v0.33.4...v0.34.0)

Updates `k8s.io/cli-runtime` from 0.33.4 to 0.34.0
- [Commits](https://github.com/kubernetes/cli-runtime/compare/v0.33.4...v0.34.0)

Updates `k8s.io/client-go` from 0.33.4 to 0.34.0
- [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kubernetes/client-go/compare/v0.33.4...v0.34.0)

Updates `sigs.k8s.io/controller-runtime` from 0.21.0 to 0.22.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.21.0...v0.22.0)

Updates `k8s.io/kubelet` from 0.33.4 to 0.34.0
- [Commits](https://github.com/kubernetes/kubelet/compare/v0.33.4...v0.34.0)

Updates `k8s.io/metrics` from 0.33.4 to 0.34.0
- [Commits](https://github.com/kubernetes/metrics/compare/v0.33.4...v0.34.0)

Updates `k8s.io/utils` from 0.0.0-20241104100929-3ea5e8cea738 to 0.0.0-20250604170112-4c0f3b243397
- [Commits](https://github.com/kubernetes/utils/commits)

---
updated-dependencies:
- dependency-name: github.com/shirou/gopsutil/v4
  dependency-version: 4.25.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: github.com/spf13/cobra
  dependency-version: 1.10.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: github.com/spf13/pflag
  dependency-version: 1.0.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: github.com/stretchr/testify
  dependency-version: 1.11.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: go.opentelemetry.io/otel
  dependency-version: 1.38.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: go.opentelemetry.io/otel/sdk
  dependency-version: 1.38.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: k8s.io/api
  dependency-version: 0.34.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: k8s.io/apiextensions-apiserver
  dependency-version: 0.34.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: k8s.io/apimachinery
  dependency-version: 0.34.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: k8s.io/apiserver
  dependency-version: 0.34.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: k8s.io/cli-runtime
  dependency-version: 0.34.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: k8s.io/client-go
  dependency-version: 0.34.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: sigs.k8s.io/controller-runtime
  dependency-version: 0.22.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: k8s.io/kubelet
  dependency-version: 0.34.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: k8s.io/metrics
  dependency-version: 0.34.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: k8s.io/utils
  dependency-version: 0.0.0-20250604170112-4c0f3b243397
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
...

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

* f

* f

* f

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-08 09:32:56 -07:00
dependabot[bot]andlnx01 34c9b5134b chore(deps): bump the security group with 3 updates (#1831)
Bumps the security group with 3 updates: [github.com/microsoft/go-mssqldb](https://github.com/microsoft/go-mssqldb), [github.com/stretchr/testify](https://github.com/stretchr/testify) and [helm.sh/helm/v3](https://github.com/helm/helm).


Updates `github.com/microsoft/go-mssqldb` from 1.9.2 to 1.9.3
- [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.9.2...v1.9.3)

Updates `github.com/stretchr/testify` from 1.10.0 to 1.11.0
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.10.0...v1.11.0)

Updates `helm.sh/helm/v3` from 3.18.5 to 3.18.6
- [Release notes](https://github.com/helm/helm/releases)
- [Commits](https://github.com/helm/helm/compare/v3.18.5...v3.18.6)

---
updated-dependencies:
- dependency-name: github.com/microsoft/go-mssqldb
  dependency-version: 1.9.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: github.com/stretchr/testify
  dependency-version: 1.11.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: helm.sh/helm/v3
  dependency-version: 3.18.6
  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>
2025-08-26 14:08:26 -04:00
dependabot[bot]andlnx01 70afffb5e3 chore(deps): bump helm.sh/helm/v3 from 3.18.5 to 3.18.6 in /examples/sdk/helm-template in the security group (#1830)
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.18.5 to 3.18.6
- [Release notes](https://github.com/helm/helm/releases)
- [Commits](https://github.com/helm/helm/compare/v3.18.5...v3.18.6)

---
updated-dependencies:
- dependency-name: helm.sh/helm/v3
  dependency-version: 3.18.6
  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>
2025-08-26 14:07:58 -04:00
Steven Crespo 983c33469e Update go to 1.24.6 (#1829) 2025-08-21 14:45:35 -07:00
dependabot[bot]andlnx01 8aede28c90 chore(deps): bump github.com/go-viper/mapstructure/v2 from 2.3.0 to 2.4.0 in the go_modules group (#1828)
chore(deps): bump github.com/go-viper/mapstructure/v2

Bumps the go_modules group with 1 update: [github.com/go-viper/mapstructure/v2](https://github.com/go-viper/mapstructure).


Updates `github.com/go-viper/mapstructure/v2` from 2.3.0 to 2.4.0
- [Release notes](https://github.com/go-viper/mapstructure/releases)
- [Changelog](https://github.com/go-viper/mapstructure/blob/main/CHANGELOG.md)
- [Commits](https://github.com/go-viper/mapstructure/compare/v2.3.0...v2.4.0)

---
updated-dependencies:
- dependency-name: github.com/go-viper/mapstructure/v2
  dependency-version: 2.4.0
  dependency-type: indirect
  dependency-group: go_modules
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-21 14:08:20 -04:00
dependabot[bot]andlnx01 d621b40bd6 chore(deps): bump github.com/hashicorp/go-getter from 1.7.8 to 1.7.9 in the go_modules group (#1827)
chore(deps): bump github.com/hashicorp/go-getter in the go_modules group

Bumps the go_modules group with 1 update: [github.com/hashicorp/go-getter](https://github.com/hashicorp/go-getter).


Updates `github.com/hashicorp/go-getter` from 1.7.8 to 1.7.9
- [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.8...v1.7.9)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/go-getter
  dependency-version: 1.7.9
  dependency-type: direct:production
  dependency-group: go_modules
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-20 14:08:31 -04:00
dependabot[bot]andlnx01 f8daf8e7ac chore(deps): bump the security group with 9 updates (#1826)
Bumps the security group with 9 updates:

| Package | From | To |
| --- | --- | --- |
| [github.com/hashicorp/go-getter](https://github.com/hashicorp/go-getter) | `1.7.8` | `1.7.9` |
| [k8s.io/api](https://github.com/kubernetes/api) | `0.33.3` | `0.33.4` |
| [k8s.io/apiextensions-apiserver](https://github.com/kubernetes/apiextensions-apiserver) | `0.33.3` | `0.33.4` |
| [k8s.io/apimachinery](https://github.com/kubernetes/apimachinery) | `0.33.3` | `0.33.4` |
| [k8s.io/apiserver](https://github.com/kubernetes/apiserver) | `0.33.3` | `0.33.4` |
| [k8s.io/cli-runtime](https://github.com/kubernetes/cli-runtime) | `0.33.3` | `0.33.4` |
| [k8s.io/client-go](https://github.com/kubernetes/client-go) | `0.33.3` | `0.33.4` |
| [k8s.io/kubelet](https://github.com/kubernetes/kubelet) | `0.33.3` | `0.33.4` |
| [k8s.io/metrics](https://github.com/kubernetes/metrics) | `0.33.3` | `0.33.4` |


Updates `github.com/hashicorp/go-getter` from 1.7.8 to 1.7.9
- [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.8...v1.7.9)

Updates `k8s.io/api` from 0.33.3 to 0.33.4
- [Commits](https://github.com/kubernetes/api/compare/v0.33.3...v0.33.4)

Updates `k8s.io/apiextensions-apiserver` from 0.33.3 to 0.33.4
- [Release notes](https://github.com/kubernetes/apiextensions-apiserver/releases)
- [Commits](https://github.com/kubernetes/apiextensions-apiserver/compare/v0.33.3...v0.33.4)

Updates `k8s.io/apimachinery` from 0.33.3 to 0.33.4
- [Commits](https://github.com/kubernetes/apimachinery/compare/v0.33.3...v0.33.4)

Updates `k8s.io/apiserver` from 0.33.3 to 0.33.4
- [Commits](https://github.com/kubernetes/apiserver/compare/v0.33.3...v0.33.4)

Updates `k8s.io/cli-runtime` from 0.33.3 to 0.33.4
- [Commits](https://github.com/kubernetes/cli-runtime/compare/v0.33.3...v0.33.4)

Updates `k8s.io/client-go` from 0.33.3 to 0.33.4
- [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kubernetes/client-go/compare/v0.33.3...v0.33.4)

Updates `k8s.io/kubelet` from 0.33.3 to 0.33.4
- [Commits](https://github.com/kubernetes/kubelet/compare/v0.33.3...v0.33.4)

Updates `k8s.io/metrics` from 0.33.3 to 0.33.4
- [Commits](https://github.com/kubernetes/metrics/compare/v0.33.3...v0.33.4)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/go-getter
  dependency-version: 1.7.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/api
  dependency-version: 0.33.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/apiextensions-apiserver
  dependency-version: 0.33.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/apimachinery
  dependency-version: 0.33.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/apiserver
  dependency-version: 0.33.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/cli-runtime
  dependency-version: 0.33.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/client-go
  dependency-version: 0.33.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/kubelet
  dependency-version: 0.33.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/metrics
  dependency-version: 0.33.4
  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>
2025-08-19 08:10:41 -04:00
dependabot[bot]andlnx01 2d5018f265 chore(deps): bump helm.sh/helm/v3 from 3.18.4 to 3.18.5 in the go_modules group (#1824)
chore(deps): bump helm.sh/helm/v3 in the go_modules group

Bumps the go_modules group with 1 update: [helm.sh/helm/v3](https://github.com/helm/helm).


Updates `helm.sh/helm/v3` from 3.18.4 to 3.18.5
- [Release notes](https://github.com/helm/helm/releases)
- [Commits](https://github.com/helm/helm/compare/v3.18.4...v3.18.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-14 14:09:11 -04:00
dependabot[bot]andlnx01 a8ca87cdc4 chore(deps): bump helm.sh/helm/v3 from 3.18.4 to 3.18.5 in /examples/sdk/helm-template in the go_modules group (#1823)
chore(deps): bump helm.sh/helm/v3

Bumps the go_modules 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.18.4 to 3.18.5
- [Release notes](https://github.com/helm/helm/releases)
- [Commits](https://github.com/helm/helm/compare/v3.18.4...v3.18.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-14 14:08:44 -04:00
dependabot[bot]andlnx01 b2f22b4cfc chore(deps): bump actions/checkout from 4 to 5 (#1820)
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '5'
  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>
2025-08-12 06:37:35 -07:00
dependabot[bot]andlnx01 9bc4e6f5ac chore(deps): bump actions/download-artifact from 4 to 5 (#1821)
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4 to 5.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '5'
  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>
2025-08-12 06:37:16 -07:00
dependabot[bot]andlnx01 64d85ef832 chore(deps): bump the security group with 4 updates (#1822)
Bumps the security group with 4 updates: [golang.org/x/mod](https://github.com/golang/mod), [golang.org/x/net](https://github.com/golang/net), [golang.org/x/sys](https://github.com/golang/sys) and [golang.org/x/text](https://github.com/golang/text).


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

Updates `golang.org/x/net` from 0.42.0 to 0.43.0
- [Commits](https://github.com/golang/net/compare/v0.42.0...v0.43.0)

Updates `golang.org/x/sys` from 0.34.0 to 0.35.0
- [Commits](https://github.com/golang/sys/compare/v0.34.0...v0.35.0)

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

---
updated-dependencies:
- dependency-name: golang.org/x/mod
  dependency-version: 0.27.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: golang.org/x/net
  dependency-version: 0.43.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: golang.org/x/sys
  dependency-version: 0.35.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: golang.org/x/text
  dependency-version: 0.28.0
  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>
2025-08-12 08:11:39 -04:00
dependabot[bot]andlnx01 da28ffb4b0 chore(deps): bump sigstore/cosign-installer from 3.9.1 to 3.9.2 (#1816)
Bumps [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer) from 3.9.1 to 3.9.2.
- [Release notes](https://github.com/sigstore/cosign-installer/releases)
- [Commits](https://github.com/sigstore/cosign-installer/compare/v3.9.1...v3.9.2)

---
updated-dependencies:
- dependency-name: sigstore/cosign-installer
  dependency-version: 3.9.2
  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>
2025-08-05 19:53:58 -07:00
dependabot[bot]andlnx01 0f07644514 chore(deps): bump the security group with 4 updates (#1819)
Bumps the security group with 4 updates: [github.com/containers/image/v5](https://github.com/containers/image), [github.com/miekg/dns](https://github.com/miekg/dns), [github.com/shirou/gopsutil/v4](https://github.com/shirou/gopsutil) and [github.com/vmware-tanzu/velero](https://github.com/vmware-tanzu/velero).


Updates `github.com/containers/image/v5` from 5.36.0 to 5.36.1
- [Release notes](https://github.com/containers/image/releases)
- [Commits](https://github.com/containers/image/compare/v5.36.0...v5.36.1)

Updates `github.com/miekg/dns` from 1.1.67 to 1.1.68
- [Changelog](https://github.com/miekg/dns/blob/master/Makefile.release)
- [Commits](https://github.com/miekg/dns/compare/v1.1.67...v1.1.68)

Updates `github.com/shirou/gopsutil/v4` from 4.25.6 to 4.25.7
- [Release notes](https://github.com/shirou/gopsutil/releases)
- [Commits](https://github.com/shirou/gopsutil/compare/v4.25.6...v4.25.7)

Updates `github.com/vmware-tanzu/velero` from 1.16.1 to 1.16.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.16.1...v1.16.2)

---
updated-dependencies:
- dependency-name: github.com/containers/image/v5
  dependency-version: 5.36.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: github.com/miekg/dns
  dependency-version: 1.1.68
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: github.com/shirou/gopsutil/v4
  dependency-version: 4.25.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: github.com/vmware-tanzu/velero
  dependency-version: 1.16.2
  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>
2025-08-05 08:12:10 -04:00
dependabot[bot]andlnx01 1eda7905c0 chore(deps): bump github.com/docker/docker from 28.3.2+incompatible to 28.3.3+incompatible in the go_modules group (#1818)
chore(deps): bump github.com/docker/docker in the go_modules group

Bumps the go_modules group with 1 update: [github.com/docker/docker](https://github.com/docker/docker).


Updates `github.com/docker/docker` from 28.3.2+incompatible to 28.3.3+incompatible
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](https://github.com/docker/docker/compare/v28.3.2...v28.3.3)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-version: 28.3.3+incompatible
  dependency-type: indirect
  dependency-group: go_modules
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-29 20:30:03 -04:00
dependabot[bot]andlnx01 0071fb20db chore(deps): bump the security group with 12 updates (#1817)
Bumps the security group with 12 updates:

| Package | From | To |
| --- | --- | --- |
| [github.com/casbin/govaluate](https://github.com/casbin/govaluate) | `1.8.0` | `1.9.0` |
| [github.com/containers/image/v5](https://github.com/containers/image) | `5.35.0` | `5.36.0` |
| [github.com/spf13/pflag](https://github.com/spf13/pflag) | `1.0.6` | `1.0.7` |
| [k8s.io/api](https://github.com/kubernetes/api) | `0.33.2` | `0.33.3` |
| [k8s.io/apiextensions-apiserver](https://github.com/kubernetes/apiextensions-apiserver) | `0.33.2` | `0.33.3` |
| [k8s.io/apimachinery](https://github.com/kubernetes/apimachinery) | `0.33.2` | `0.33.3` |
| [k8s.io/apiserver](https://github.com/kubernetes/apiserver) | `0.33.2` | `0.33.3` |
| [k8s.io/cli-runtime](https://github.com/kubernetes/cli-runtime) | `0.33.2` | `0.33.3` |
| [k8s.io/client-go](https://github.com/kubernetes/client-go) | `0.33.2` | `0.33.3` |
| [k8s.io/kubelet](https://github.com/kubernetes/kubelet) | `0.33.2` | `0.33.3` |
| [k8s.io/metrics](https://github.com/kubernetes/metrics) | `0.33.2` | `0.33.3` |
| [sigs.k8s.io/yaml](https://github.com/kubernetes-sigs/yaml) | `1.5.0` | `1.6.0` |


Updates `github.com/casbin/govaluate` from 1.8.0 to 1.9.0
- [Release notes](https://github.com/casbin/govaluate/releases)
- [Changelog](https://github.com/casbin/govaluate/blob/master/.releaserc.json)
- [Commits](https://github.com/casbin/govaluate/compare/v1.8.0...v1.9.0)

Updates `github.com/containers/image/v5` from 5.35.0 to 5.36.0
- [Release notes](https://github.com/containers/image/releases)
- [Commits](https://github.com/containers/image/compare/v5.35.0...v5.36.0)

Updates `github.com/spf13/pflag` from 1.0.6 to 1.0.7
- [Release notes](https://github.com/spf13/pflag/releases)
- [Commits](https://github.com/spf13/pflag/compare/v1.0.6...v1.0.7)

Updates `k8s.io/api` from 0.33.2 to 0.33.3
- [Commits](https://github.com/kubernetes/api/compare/v0.33.2...v0.33.3)

Updates `k8s.io/apiextensions-apiserver` from 0.33.2 to 0.33.3
- [Release notes](https://github.com/kubernetes/apiextensions-apiserver/releases)
- [Commits](https://github.com/kubernetes/apiextensions-apiserver/compare/v0.33.2...v0.33.3)

Updates `k8s.io/apimachinery` from 0.33.2 to 0.33.3
- [Commits](https://github.com/kubernetes/apimachinery/compare/v0.33.2...v0.33.3)

Updates `k8s.io/apiserver` from 0.33.2 to 0.33.3
- [Commits](https://github.com/kubernetes/apiserver/compare/v0.33.2...v0.33.3)

Updates `k8s.io/cli-runtime` from 0.33.2 to 0.33.3
- [Commits](https://github.com/kubernetes/cli-runtime/compare/v0.33.2...v0.33.3)

Updates `k8s.io/client-go` from 0.33.2 to 0.33.3
- [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kubernetes/client-go/compare/v0.33.2...v0.33.3)

Updates `k8s.io/kubelet` from 0.33.2 to 0.33.3
- [Commits](https://github.com/kubernetes/kubelet/compare/v0.33.2...v0.33.3)

Updates `k8s.io/metrics` from 0.33.2 to 0.33.3
- [Commits](https://github.com/kubernetes/metrics/compare/v0.33.2...v0.33.3)

Updates `sigs.k8s.io/yaml` from 1.5.0 to 1.6.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.5.0...v1.6.0)

---
updated-dependencies:
- dependency-name: github.com/casbin/govaluate
  dependency-version: 1.9.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: github.com/containers/image/v5
  dependency-version: 5.36.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: github.com/spf13/pflag
  dependency-version: 1.0.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/api
  dependency-version: 0.33.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/apiextensions-apiserver
  dependency-version: 0.33.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/apimachinery
  dependency-version: 0.33.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/apiserver
  dependency-version: 0.33.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/cli-runtime
  dependency-version: 0.33.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/client-go
  dependency-version: 0.33.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/kubelet
  dependency-version: 0.33.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: k8s.io/metrics
  dependency-version: 0.33.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: sigs.k8s.io/yaml
  dependency-version: 1.6.0
  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>
2025-07-29 02:10:53 -04:00
dependabot[bot]andlnx01 c70118a01c chore(deps): bump sigs.k8s.io/yaml from 1.5.0 to 1.6.0 in /examples/sdk/helm-template in the security group (#1815)
chore(deps): bump sigs.k8s.io/yaml

Bumps the security group in /examples/sdk/helm-template with 1 update: [sigs.k8s.io/yaml](https://github.com/kubernetes-sigs/yaml).


Updates `sigs.k8s.io/yaml` from 1.5.0 to 1.6.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.5.0...v1.6.0)

---
updated-dependencies:
- dependency-name: sigs.k8s.io/yaml
  dependency-version: 1.6.0
  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>
2025-07-29 02:09:59 -04:00
João Antunes 13c3ff48a5 chore(ci): fix go-release (#1814) 2025-07-28 16:59:09 +01:00
João Antunes b261d4a70d chore(ci): make sure our CI builds the prod binaries (#1813)
* chore(ci): make sure our CI builds the prod binaries

* chore(ci): turns out its all about go mod tidy

* chore(ci): turns out its all about go mod tidy
2025-07-28 16:24:15 +01:00
João Antunes 9ec487a2b6 fix(build): otel indirect dep preventing build (#1812) 2025-07-28 14:23:59 +01:00
Diamon Wiggins 2861425293 feat(run-pod): allow image pull retries in run pod collector (#1811)
* allow image pull retries in run pod collector

* fix formatting
2025-07-25 11:30:14 -04:00
dependabot[bot]andlnx01 18515b481a chore(deps): bump golang.org/x/net from 0.41.0 to 0.42.0 in the security group (#1810)
chore(deps): bump golang.org/x/net in the security group

Bumps the security group with 1 update: [golang.org/x/net](https://github.com/golang/net).


Updates `golang.org/x/net` from 0.41.0 to 0.42.0
- [Commits](https://github.com/golang/net/compare/v0.41.0...v0.42.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-version: 0.42.0
  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>
2025-07-15 08:11:25 -04:00
dependabot[bot]andlnx01 a0eb0d3a15 chore(deps): bump the security group across 1 directory with 21 updates (#1809)
---
updated-dependencies:
- dependency-name: github.com/casbin/govaluate
  dependency-version: 1.8.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: github.com/cilium/ebpf
  dependency-version: 0.19.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: github.com/containers/image/v5
  dependency-version: 5.35.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: github.com/go-logr/logr
  dependency-version: 1.4.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: github.com/go-sql-driver/mysql
  dependency-version: 1.9.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: github.com/jackc/pgx/v5
  dependency-version: 5.7.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: github.com/microsoft/go-mssqldb
  dependency-version: 1.9.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: github.com/miekg/dns
  dependency-version: 1.1.67
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: github.com/shirou/gopsutil/v4
  dependency-version: 4.25.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: github.com/vishvananda/netlink
  dependency-version: 1.3.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: github.com/vmware-tanzu/velero
  dependency-version: 1.16.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: go.opentelemetry.io/otel
  dependency-version: 1.37.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: go.opentelemetry.io/otel/sdk
  dependency-version: 1.37.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: golang.org/x/mod
  dependency-version: 0.26.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: golang.org/x/sync
  dependency-version: 0.16.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: sigs.k8s.io/controller-runtime
  dependency-version: 0.21.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: golang.org/x/net
  dependency-version: 0.41.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: golang.org/x/sys
  dependency-version: 0.34.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: golang.org/x/text
  dependency-version: 0.27.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: k8s.io/kubelet
  dependency-version: 0.33.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: sigs.k8s.io/yaml
  dependency-version: 1.5.0
  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>
2025-07-10 18:08:28 +00:00
dependabot[bot] 733d401b0f chore(deps): bump helm.sh/helm/v3 from 3.17.3 to 3.18.4 in the go_modules group (#1805) 2025-07-10 09:43:19 -07:00
Diamon Wiggins 7a6bffeff5 chore: fix noisy info logs (#1808)
* refine logging

* keep progress message at level 0
2025-07-09 20:58:47 -04:00
Ethan Mosbaugh 38d8a45171 fix(host-analyze): certificate analyzer wrong file path (#1807) 2025-07-09 09:32:04 -04:00
dependabot[bot]andlnx01 f34c67ec83 chore(deps): bump helm.sh/helm/v3 from 3.18.3 to 3.18.4 in /examples/sdk/helm-template in the go_modules group (#1806)
chore(deps): bump helm.sh/helm/v3

Bumps the go_modules 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.18.3 to 3.18.4
- [Release notes](https://github.com/helm/helm/releases)
- [Commits](https://github.com/helm/helm/compare/v3.18.3...v3.18.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-09 00:28:34 +00:00
Evans Mungai ced5bd6d0d chore: use go.mod file in actions setup-go (#1804)
* chore: use go.mod file in actions setup-go

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

* Remove unnecessary setup up step

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

---------

Signed-off-by: Evans Mungai <evans@replicated.com>
2025-07-04 06:30:34 -07:00
Xav Paice 54f466a25d update Go to 1.24.4 (#1803) 2025-07-04 11:41:10 +01:00
dependabot[bot]andlnx01 fa65beaddc chore(deps): bump sigstore/cosign-installer from 3.8.1 to 3.9.1 (#1798)
Bumps [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer) from 3.8.1 to 3.9.1.
- [Release notes](https://github.com/sigstore/cosign-installer/releases)
- [Commits](https://github.com/sigstore/cosign-installer/compare/v3.8.1...v3.9.1)

---
updated-dependencies:
- dependency-name: sigstore/cosign-installer
  dependency-version: 3.9.1
  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>
2025-07-04 11:40:40 +01:00
dependabot[bot]andlnx01 ae64bba900 chore(deps): bump sigs.k8s.io/yaml from 1.4.0 to 1.5.0 in /examples/sdk/helm-template in the security group (#1802)
chore(deps): bump sigs.k8s.io/yaml

Bumps the security group in /examples/sdk/helm-template with 1 update: [sigs.k8s.io/yaml](https://github.com/kubernetes-sigs/yaml).


Updates `sigs.k8s.io/yaml` from 1.4.0 to 1.5.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.4.0...v1.5.0)

---
updated-dependencies:
- dependency-name: sigs.k8s.io/yaml
  dependency-version: 1.5.0
  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>
2025-07-01 06:09:27 +00:00
Diamon Wiggins 989780af69 feat: allow secrets collector to retreive all key data if specified (#1801)
* allow secrets collector retreival all key data if specified

* add new line

* remove unneeded comments
2025-06-30 10:06:14 -04:00
dependabot[bot]andlnx01 4281c67066 chore(deps): bump github.com/go-viper/mapstructure/v2 from 2.2.1 to 2.3.0 in the go_modules group (#1799)
chore(deps): bump github.com/go-viper/mapstructure/v2

Bumps the go_modules group with 1 update: [github.com/go-viper/mapstructure/v2](https://github.com/go-viper/mapstructure).


Updates `github.com/go-viper/mapstructure/v2` from 2.2.1 to 2.3.0
- [Release notes](https://github.com/go-viper/mapstructure/releases)
- [Changelog](https://github.com/go-viper/mapstructure/blob/main/CHANGELOG.md)
- [Commits](https://github.com/go-viper/mapstructure/compare/v2.2.1...v2.3.0)

---
updated-dependencies:
- dependency-name: github.com/go-viper/mapstructure/v2
  dependency-version: 2.3.0
  dependency-type: indirect
  dependency-group: go_modules
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-27 18:08:16 +00:00
dependabot[bot]andlnx01 089da2667f chore(deps): bump helm.sh/helm/v3 from 3.18.2 to 3.18.3 in /examples/sdk/helm-template in the security group (#1797)
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.18.2 to 3.18.3
- [Release notes](https://github.com/helm/helm/releases)
- [Commits](https://github.com/helm/helm/compare/v3.18.2...v3.18.3)

---
updated-dependencies:
- dependency-name: helm.sh/helm/v3
  dependency-version: 3.18.3
  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>
2025-06-17 06:09:12 +00:00
Ethan Mosbaugh a4a387eb0e chore: CVE-2024-0406 remove github.com/mholt/archiver/v3 dependency (#1793) 2025-06-06 11:35:56 -07:00
dependabot[bot]andlnx01 0b860b1afe chore(deps): bump helm.sh/helm/v3 from 3.18.0 to 3.18.2 in /examples/sdk/helm-template in the security group (#1792)
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.18.0 to 3.18.2
- [Release notes](https://github.com/helm/helm/releases)
- [Commits](https://github.com/helm/helm/compare/v3.18.0...v3.18.2)

---
updated-dependencies:
- dependency-name: helm.sh/helm/v3
  dependency-version: 3.18.2
  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>
2025-06-03 00:27:56 +00:00
dependabot[bot]andlnx01 af64eacfdb chore(deps): bump helm.sh/helm/v3 from 3.17.3 to 3.18.0 in /examples/sdk/helm-template in the security group (#1788)
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.17.3 to 3.18.0
- [Release notes](https://github.com/helm/helm/releases)
- [Commits](https://github.com/helm/helm/compare/v3.17.3...v3.18.0)

---
updated-dependencies:
- dependency-name: helm.sh/helm/v3
  dependency-version: 3.18.0
  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>
2025-05-20 00:27:39 +00:00
Pavan Sokke Nagaraj c4c0860bad Update daily-scan.yaml with ubuntu-latest (#1782) 2025-05-14 20:34:42 -07:00
Dmitriy Ivolgin 03efedf714 Follow logs when using runDaemonSet and runPod collectors (#1783)
Follow logs when using runDaemonSet collector

Signed-off-by: divolgin <dmitriy@replicated.com>
2025-05-09 12:54:28 -07:00
9bca9c5245 chore(deps): bump github.com/distribution/distribution/v3 from 3.0.0-rc.3 to 3.0.0 (#1771)
* chore(deps): bump github.com/distribution/distribution/v3

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

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

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

* update go

* use constant format strings

* f

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Andrew Lavery <laverya@umich.edu>
2025-04-21 16:45:47 +00:00
Luke Amdor 3a457d11fc feat: add timestamps flag to logs collector (#1776)
* feat: add timestamps falg to logs collector

Kubernetes logs can be transmitted with the captured timestamps. This is useful for containers that do not log with timestamps. So I'm exposing that as a flag.

* fix: update schemas
2025-04-17 10:51:07 -04:00
dependabot[bot]andlnx01 7cc5ce2941 chore(deps): bump the security group with 2 updates (#1775)
Bumps the security group with 2 updates: [github.com/vmware-tanzu/velero](https://github.com/vmware-tanzu/velero) and [periph.io/x/host/v3](https://github.com/periph/host).


Updates `github.com/vmware-tanzu/velero` from 1.15.2 to 1.16.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.15.2...v1.16.0)

Updates `periph.io/x/host/v3` from 3.8.4 to 3.8.5
- [Release notes](https://github.com/periph/host/releases)
- [Commits](https://github.com/periph/host/compare/v3.8.4...v3.8.5)

---
updated-dependencies:
- dependency-name: github.com/vmware-tanzu/velero
  dependency-version: 1.16.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: periph.io/x/host/v3
  dependency-version: 3.8.5
  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>
2025-04-15 00:25:59 +00:00
dependabot[bot]andlnx01 48fc5b151a chore(deps): bump helm.sh/helm/v3 from 3.17.2 to 3.17.3 in the go_modules group (#1773)
chore(deps): bump helm.sh/helm/v3 in the go_modules group

Bumps the go_modules group with 1 update: [helm.sh/helm/v3](https://github.com/helm/helm).


Updates `helm.sh/helm/v3` from 3.17.2 to 3.17.3
- [Release notes](https://github.com/helm/helm/releases)
- [Commits](https://github.com/helm/helm/compare/v3.17.2...v3.17.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-10 18:08:28 +00:00
dependabot[bot]andlnx01 9419e84791 chore(deps): bump helm.sh/helm/v3 from 3.17.2 to 3.17.3 in /examples/sdk/helm-template in the go_modules group (#1772)
chore(deps): bump helm.sh/helm/v3

Bumps the go_modules 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.17.2 to 3.17.3
- [Release notes](https://github.com/helm/helm/releases)
- [Commits](https://github.com/helm/helm/compare/v3.17.2...v3.17.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-10 18:07:54 +00:00
dependabot[bot]andlnx01 08beae35d2 chore(deps): bump the security group with 8 updates (#1770)
Bumps the security group with 8 updates:

| Package | From | To |
| --- | --- | --- |
| [github.com/cilium/ebpf](https://github.com/cilium/ebpf) | `0.17.3` | `0.18.0` |
| [github.com/go-sql-driver/mysql](https://github.com/go-sql-driver/mysql) | `1.9.1` | `1.9.2` |
| [github.com/miekg/dns](https://github.com/miekg/dns) | `1.1.64` | `1.1.65` |
| [github.com/shirou/gopsutil/v4](https://github.com/shirou/gopsutil) | `4.25.2` | `4.25.3` |
| [golang.org/x/sync](https://github.com/golang/sync) | `0.12.0` | `0.13.0` |
| [golang.org/x/net](https://github.com/golang/net) | `0.38.0` | `0.39.0` |
| [golang.org/x/sys](https://github.com/golang/sys) | `0.31.0` | `0.32.0` |
| [golang.org/x/text](https://github.com/golang/text) | `0.23.0` | `0.24.0` |


Updates `github.com/cilium/ebpf` from 0.17.3 to 0.18.0
- [Release notes](https://github.com/cilium/ebpf/releases)
- [Commits](https://github.com/cilium/ebpf/compare/v0.17.3...v0.18.0)

Updates `github.com/go-sql-driver/mysql` from 1.9.1 to 1.9.2
- [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.9.1...v1.9.2)

Updates `github.com/miekg/dns` from 1.1.64 to 1.1.65
- [Changelog](https://github.com/miekg/dns/blob/master/Makefile.release)
- [Commits](https://github.com/miekg/dns/compare/v1.1.64...v1.1.65)

Updates `github.com/shirou/gopsutil/v4` from 4.25.2 to 4.25.3
- [Release notes](https://github.com/shirou/gopsutil/releases)
- [Commits](https://github.com/shirou/gopsutil/compare/v4.25.2...v4.25.3)

Updates `golang.org/x/sync` from 0.12.0 to 0.13.0
- [Commits](https://github.com/golang/sync/compare/v0.12.0...v0.13.0)

Updates `golang.org/x/net` from 0.38.0 to 0.39.0
- [Commits](https://github.com/golang/net/compare/v0.38.0...v0.39.0)

Updates `golang.org/x/sys` from 0.31.0 to 0.32.0
- [Commits](https://github.com/golang/sys/compare/v0.31.0...v0.32.0)

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

---
updated-dependencies:
- dependency-name: github.com/cilium/ebpf
  dependency-version: 0.18.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: github.com/go-sql-driver/mysql
  dependency-version: 1.9.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: github.com/miekg/dns
  dependency-version: 1.1.65
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: github.com/shirou/gopsutil/v4
  dependency-version: 4.25.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: golang.org/x/sync
  dependency-version: 0.13.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: golang.org/x/net
  dependency-version: 0.39.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: golang.org/x/sys
  dependency-version: 0.32.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: golang.org/x/text
  dependency-version: 0.24.0
  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>
2025-04-08 06:08:21 +00:00
Andrew Lavery ab7f50d0ce improve detection of tanzu clusters (#1769) 2025-04-03 11:25:44 -07:00
dependabot[bot] cbb22e27a8 chore(deps): bump golang.org/x/net from 0.35.0 to 0.36.0 in /examples/sdk/helm-template in the go_modules group (#1759) 2025-04-01 15:30:42 +00:00
dependabot[bot]andlnx01 87d50af689 chore(deps): bump github.com/containerd/containerd from 1.7.24 to 1.7.27 in the go_modules group (#1768)
chore(deps): bump github.com/containerd/containerd

Bumps the go_modules group with 1 update: [github.com/containerd/containerd](https://github.com/containerd/containerd).


Updates `github.com/containerd/containerd` from 1.7.24 to 1.7.27
- [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.24...v1.7.27)

---
updated-dependencies:
- dependency-name: github.com/containerd/containerd
  dependency-version: 1.7.27
  dependency-type: indirect
  dependency-group: go_modules
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-01 12:10:20 +00:00
dependabot[bot]andlnx01 1aea8d0373 chore(deps): bump the security group with 5 updates (#1766)
Bumps the security group with 5 updates:

| Package | From | To |
| --- | --- | --- |
| [github.com/containers/image/v5](https://github.com/containers/image) | `5.34.2` | `5.34.3` |
| [github.com/jackc/pgx/v5](https://github.com/jackc/pgx) | `5.7.3` | `5.7.4` |
| [github.com/spf13/viper](https://github.com/spf13/viper) | `1.20.0` | `1.20.1` |
| [golang.org/x/net](https://github.com/golang/net) | `0.37.0` | `0.38.0` |
| [periph.io/x/host/v3](https://github.com/periph/host) | `3.8.3` | `3.8.4` |


Updates `github.com/containers/image/v5` from 5.34.2 to 5.34.3
- [Release notes](https://github.com/containers/image/releases)
- [Commits](https://github.com/containers/image/compare/v5.34.2...v5.34.3)

Updates `github.com/jackc/pgx/v5` from 5.7.3 to 5.7.4
- [Changelog](https://github.com/jackc/pgx/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jackc/pgx/compare/v5.7.3...v5.7.4)

Updates `github.com/spf13/viper` from 1.20.0 to 1.20.1
- [Release notes](https://github.com/spf13/viper/releases)
- [Commits](https://github.com/spf13/viper/compare/v1.20.0...v1.20.1)

Updates `golang.org/x/net` from 0.37.0 to 0.38.0
- [Commits](https://github.com/golang/net/compare/v0.37.0...v0.38.0)

Updates `periph.io/x/host/v3` from 3.8.3 to 3.8.4
- [Release notes](https://github.com/periph/host/releases)
- [Commits](https://github.com/periph/host/compare/v3.8.3...v3.8.4)

---
updated-dependencies:
- dependency-name: github.com/containers/image/v5
  dependency-version: 5.34.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: github.com/jackc/pgx/v5
  dependency-version: 5.7.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: github.com/spf13/viper
  dependency-version: 1.20.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: golang.org/x/net
  dependency-version: 0.38.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: periph.io/x/host/v3
  dependency-version: 3.8.4
  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>
2025-04-01 06:08:29 +00:00
dependabot[bot]andlnx01 2b1b942a9f chore(deps): bump the security group across 1 directory with 22 updates (#1764)
Bumps the security group with 17 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [github.com/containers/image/v5](https://github.com/containers/image) | `5.34.1` | `5.34.2` |
| [github.com/go-sql-driver/mysql](https://github.com/go-sql-driver/mysql) | `1.9.0` | `1.9.1` |
| [github.com/jackc/pgx/v5](https://github.com/jackc/pgx) | `5.7.2` | `5.7.3` |
| [github.com/miekg/dns](https://github.com/miekg/dns) | `1.1.63` | `1.1.64` |
| [github.com/spf13/viper](https://github.com/spf13/viper) | `1.19.0` | `1.20.0` |
| [go.opentelemetry.io/otel](https://github.com/open-telemetry/opentelemetry-go) | `1.34.0` | `1.35.0` |
| [go.opentelemetry.io/otel/sdk](https://github.com/open-telemetry/opentelemetry-go) | `1.34.0` | `1.35.0` |
| [golang.org/x/mod](https://github.com/golang/mod) | `0.23.0` | `0.24.0` |
| [golang.org/x/sync](https://github.com/golang/sync) | `0.11.0` | `0.12.0` |
| [k8s.io/api](https://github.com/kubernetes/api) | `0.32.2` | `0.32.3` |
| [k8s.io/apiextensions-apiserver](https://github.com/kubernetes/apiextensions-apiserver) | `0.32.2` | `0.32.3` |
| [k8s.io/cli-runtime](https://github.com/kubernetes/cli-runtime) | `0.32.2` | `0.32.3` |
| [sigs.k8s.io/controller-runtime](https://github.com/kubernetes-sigs/controller-runtime) | `0.20.2` | `0.20.4` |
| [golang.org/x/net](https://github.com/golang/net) | `0.35.0` | `0.37.0` |
| [helm.sh/helm/v3](https://github.com/helm/helm) | `3.17.1` | `3.17.2` |
| [k8s.io/kubelet](https://github.com/kubernetes/kubelet) | `0.32.2` | `0.32.3` |
| [k8s.io/metrics](https://github.com/kubernetes/metrics) | `0.32.2` | `0.32.3` |



Updates `github.com/containers/image/v5` from 5.34.1 to 5.34.2
- [Release notes](https://github.com/containers/image/releases)
- [Commits](https://github.com/containers/image/compare/v5.34.1...v5.34.2)

Updates `github.com/go-sql-driver/mysql` from 1.9.0 to 1.9.1
- [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.9.0...v1.9.1)

Updates `github.com/jackc/pgx/v5` from 5.7.2 to 5.7.3
- [Changelog](https://github.com/jackc/pgx/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jackc/pgx/compare/v5.7.2...v5.7.3)

Updates `github.com/miekg/dns` from 1.1.63 to 1.1.64
- [Changelog](https://github.com/miekg/dns/blob/master/Makefile.release)
- [Commits](https://github.com/miekg/dns/compare/v1.1.63...v1.1.64)

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

Updates `go.opentelemetry.io/otel` from 1.34.0 to 1.35.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.34.0...v1.35.0)

Updates `go.opentelemetry.io/otel/sdk` from 1.34.0 to 1.35.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.34.0...v1.35.0)

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

Updates `golang.org/x/sync` from 0.11.0 to 0.12.0
- [Commits](https://github.com/golang/sync/compare/v0.11.0...v0.12.0)

Updates `k8s.io/api` from 0.32.2 to 0.32.3
- [Commits](https://github.com/kubernetes/api/compare/v0.32.2...v0.32.3)

Updates `k8s.io/apiextensions-apiserver` from 0.32.2 to 0.32.3
- [Release notes](https://github.com/kubernetes/apiextensions-apiserver/releases)
- [Commits](https://github.com/kubernetes/apiextensions-apiserver/compare/v0.32.2...v0.32.3)

Updates `k8s.io/apimachinery` from 0.32.2 to 0.32.3
- [Commits](https://github.com/kubernetes/apimachinery/compare/v0.32.2...v0.32.3)

Updates `k8s.io/apiserver` from 0.32.2 to 0.32.3
- [Commits](https://github.com/kubernetes/apiserver/compare/v0.32.2...v0.32.3)

Updates `k8s.io/cli-runtime` from 0.32.2 to 0.32.3
- [Commits](https://github.com/kubernetes/cli-runtime/compare/v0.32.2...v0.32.3)

Updates `k8s.io/client-go` from 0.32.2 to 0.32.3
- [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kubernetes/client-go/compare/v0.32.2...v0.32.3)

Updates `sigs.k8s.io/controller-runtime` from 0.20.2 to 0.20.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.20.2...v0.20.4)

Updates `golang.org/x/net` from 0.35.0 to 0.37.0
- [Commits](https://github.com/golang/net/compare/v0.35.0...v0.37.0)

Updates `golang.org/x/sys` from 0.30.0 to 0.31.0
- [Commits](https://github.com/golang/sys/compare/v0.30.0...v0.31.0)

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

Updates `helm.sh/helm/v3` from 3.17.1 to 3.17.2
- [Release notes](https://github.com/helm/helm/releases)
- [Commits](https://github.com/helm/helm/compare/v3.17.1...v3.17.2)

Updates `k8s.io/kubelet` from 0.32.2 to 0.32.3
- [Commits](https://github.com/kubernetes/kubelet/compare/v0.32.2...v0.32.3)

Updates `k8s.io/metrics` from 0.32.2 to 0.32.3
- [Commits](https://github.com/kubernetes/metrics/compare/v0.32.2...v0.32.3)

---
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/go-sql-driver/mysql
  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-patch
  dependency-group: security
- dependency-name: github.com/miekg/dns
  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: 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: 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: 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
- 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>
2025-03-25 06:08:32 +00:00
Ethan Mosbaugh 641c195db3 fix(collect.runPod): does not delete image pull secrets without name in spec (#1761)
* fix(collect.runPod): fix deleting image pull secrets

* f

* f
2025-03-17 16:21:28 -05:00
Johannes Tuchscherer ef1cd66b1e Handling the case when the Cluster Analyzer doesn't find a resource (#1760)
* Handling the case when the Cluster Analyzer doesn't find a resource

* Add namespace information to Resource not found fail message
2025-03-14 11:22:49 -07:00
Greg Schofield 64c63d3f7a Log namespace when analyzing deployment status (#1757) 2025-03-12 13:49:15 +00:00
Johannes Tuchscherer 9577d602dd Remove the hard coding of the cosign release [sc-77445] (#1756) 2025-03-11 13:02:10 -05:00
Johannes TuchschererandAndrew Lavery 69889c376a Updating the cosign library for Github Actions (#1752)
* Updating the cosign library for Github Actions

* we have decided to use rekor

---------

Co-authored-by: Andrew Lavery <laverya@umich.edu>
2025-03-10 21:12:17 +00:00
Andrew Lavery 9d9b3c565c add additional test cases to the host os info analyzer (#1754) 2025-03-06 16:57:59 -06:00
Johannes TuchschererandAndrew Lavery 3665d25abf Http comperators (#1753)
* Allowing more comperators for the http analyzer

* test

* Update pkg/analyze/host_http.go

Co-authored-by: Andrew Lavery <laverya@umich.edu>

---------

Co-authored-by: Andrew Lavery <laverya@umich.edu>
2025-03-06 21:40:47 +00:00
dependabot[bot]andlnx01 c770c32c2e chore(deps): bump the security group with 4 updates (#1749)
Bumps the security group with 4 updates: [github.com/containers/image/v5](https://github.com/containers/image), [github.com/opencontainers/image-spec](https://github.com/opencontainers/image-spec), [github.com/shirou/gopsutil/v4](https://github.com/shirou/gopsutil) and [github.com/opencontainers/runtime-spec](https://github.com/opencontainers/runtime-spec).


Updates `github.com/containers/image/v5` from 5.34.0 to 5.34.1
- [Release notes](https://github.com/containers/image/releases)
- [Commits](https://github.com/containers/image/compare/v5.34.0...v5.34.1)

Updates `github.com/opencontainers/image-spec` from 1.1.0 to 1.1.1
- [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...v1.1.1)

Updates `github.com/shirou/gopsutil/v4` from 4.25.1 to 4.25.2
- [Release notes](https://github.com/shirou/gopsutil/releases)
- [Commits](https://github.com/shirou/gopsutil/compare/v4.25.1...v4.25.2)

Updates `github.com/opencontainers/runtime-spec` from 1.2.0 to 1.2.1
- [Release notes](https://github.com/opencontainers/runtime-spec/releases)
- [Changelog](https://github.com/opencontainers/runtime-spec/blob/main/ChangeLog)
- [Commits](https://github.com/opencontainers/runtime-spec/compare/v1.2.0...v1.2.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/opencontainers/image-spec
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: github.com/shirou/gopsutil/v4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: github.com/opencontainers/runtime-spec
  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>
2025-03-04 00:24:01 +00:00
dependabot[bot]andlnx01 b59afdda79 chore(deps): bump github.com/go-sql-driver/mysql from 1.8.1 to 1.9.0 in the security group (#1747)
chore(deps): bump github.com/go-sql-driver/mysql in the security group

Bumps the security group with 1 update: [github.com/go-sql-driver/mysql](https://github.com/go-sql-driver/mysql).


Updates `github.com/go-sql-driver/mysql` from 1.8.1 to 1.9.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.8.1...v1.9.0)

---
updated-dependencies:
- dependency-name: github.com/go-sql-driver/mysql
  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>
2025-02-25 00:24:05 +00:00
Salah Al Saleh 97dcae9fc7 Ability to use sprig functions in analyzer templates (#1745)
* Ability to use sprig functions in analyzer templates
2025-02-21 08:10:46 -08:00
Ethan Mosbaugh b80f38a9a0 fix(redact): multi-line redactors strip empty lines (#1742) 2025-02-20 21:55:05 -05:00
Andrew Lavery dca4e675fa update shirou/gopsutil to v4 (#1744) 2025-02-20 16:04:03 -08:00
Andrew Lavery fb9ea281cb improve the host OS collector and analyzer (#1743)
The OS version analyzer did not allow checking for things like "redhat 8.x" - this equates to >= 8 && < 9 in the new code.

Also, we previously only collected the OS name (like redhat, centos, or ubuntu) not the OS family (which would be rhel, rhel, and debian for the previous OSes) - this greatly reduces the number of cases required in an analyzer.
2025-02-20 13:03:53 -08:00
Ethan Mosbaugh 51c3a0c40f fix(host-preflights): buildtin kernel modules file from wrong path (#1741)
* fix(host-preflights): buildtin kernel modules file from wrong path

* f

* f

* f

* f
2025-02-18 16:19:58 -05:00
dependabot[bot]andlnx01 f3b3085456 chore(deps): bump the security group with 12 updates (#1740)
Bumps the security group with 12 updates:

| Package | From | To |
| --- | --- | --- |
| [github.com/cilium/ebpf](https://github.com/cilium/ebpf) | `0.17.2` | `0.17.3` |
| [github.com/spf13/cobra](https://github.com/spf13/cobra) | `1.8.1` | `1.9.1` |
| [k8s.io/api](https://github.com/kubernetes/api) | `0.32.1` | `0.32.2` |
| [k8s.io/apiextensions-apiserver](https://github.com/kubernetes/apiextensions-apiserver) | `0.32.1` | `0.32.2` |
| [k8s.io/apimachinery](https://github.com/kubernetes/apimachinery) | `0.32.1` | `0.32.2` |
| [k8s.io/apiserver](https://github.com/kubernetes/apiserver) | `0.32.1` | `0.32.2` |
| [k8s.io/cli-runtime](https://github.com/kubernetes/cli-runtime) | `0.32.1` | `0.32.2` |
| [k8s.io/client-go](https://github.com/kubernetes/client-go) | `0.32.1` | `0.32.2` |
| [sigs.k8s.io/controller-runtime](https://github.com/kubernetes-sigs/controller-runtime) | `0.20.1` | `0.20.2` |
| [helm.sh/helm/v3](https://github.com/helm/helm) | `3.17.0` | `3.17.1` |
| [k8s.io/kubelet](https://github.com/kubernetes/kubelet) | `0.32.1` | `0.32.2` |
| [k8s.io/metrics](https://github.com/kubernetes/metrics) | `0.32.1` | `0.32.2` |


Updates `github.com/cilium/ebpf` from 0.17.2 to 0.17.3
- [Release notes](https://github.com/cilium/ebpf/releases)
- [Commits](https://github.com/cilium/ebpf/compare/v0.17.2...v0.17.3)

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

Updates `k8s.io/api` from 0.32.1 to 0.32.2
- [Commits](https://github.com/kubernetes/api/compare/v0.32.1...v0.32.2)

Updates `k8s.io/apiextensions-apiserver` from 0.32.1 to 0.32.2
- [Release notes](https://github.com/kubernetes/apiextensions-apiserver/releases)
- [Commits](https://github.com/kubernetes/apiextensions-apiserver/compare/v0.32.1...v0.32.2)

Updates `k8s.io/apimachinery` from 0.32.1 to 0.32.2
- [Commits](https://github.com/kubernetes/apimachinery/compare/v0.32.1...v0.32.2)

Updates `k8s.io/apiserver` from 0.32.1 to 0.32.2
- [Commits](https://github.com/kubernetes/apiserver/compare/v0.32.1...v0.32.2)

Updates `k8s.io/cli-runtime` from 0.32.1 to 0.32.2
- [Commits](https://github.com/kubernetes/cli-runtime/compare/v0.32.1...v0.32.2)

Updates `k8s.io/client-go` from 0.32.1 to 0.32.2
- [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kubernetes/client-go/compare/v0.32.1...v0.32.2)

Updates `sigs.k8s.io/controller-runtime` from 0.20.1 to 0.20.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.20.1...v0.20.2)

Updates `helm.sh/helm/v3` from 3.17.0 to 3.17.1
- [Release notes](https://github.com/helm/helm/releases)
- [Commits](https://github.com/helm/helm/compare/v3.17.0...v3.17.1)

Updates `k8s.io/kubelet` from 0.32.1 to 0.32.2
- [Commits](https://github.com/kubernetes/kubelet/compare/v0.32.1...v0.32.2)

Updates `k8s.io/metrics` from 0.32.1 to 0.32.2
- [Commits](https://github.com/kubernetes/metrics/compare/v0.32.1...v0.32.2)

---
updated-dependencies:
- dependency-name: github.com/cilium/ebpf
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
- dependency-name: github.com/spf13/cobra
  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: sigs.k8s.io/controller-runtime
  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>
2025-02-18 00:23:27 +00:00
dependabot[bot]andlnx01 5ce7d1fd99 chore(deps): bump helm.sh/helm/v3 from 3.17.0 to 3.17.1 in /examples/sdk/helm-template in the security group (#1739)
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.17.0 to 3.17.1
- [Release notes](https://github.com/helm/helm/releases)
- [Commits](https://github.com/helm/helm/compare/v3.17.0...v3.17.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>
2025-02-18 00:22:57 +00:00
Ethan Mosbaugh 8e1dc9c5cb fix(preflights): builtin kernel modules file may be not found (#1738) 2025-02-17 15:54:38 -08:00
Ethan Mosbaugh 923293e79a fix(preflights): support for builtin kernel modules (#1737)
* fix(preflights): support for builtin kernel modules

* f
2025-02-17 16:57:44 -06:00
Ethan Mosbaugh ae2b5d1311 fix(ci): remove windows build from goreleaser (#1736) 2025-02-13 21:55:12 +00:00
Salah Al Saleh d5a6b19417 Add a host analyzer to check if a subnet contains an IP address (#1735)
* Add a host collector / analyzer to check if a subnet contains an IP address
2025-02-13 13:16:59 -08:00
Ethan Mosbaugh 716dda221d fix(host.kernelModules): /lib/modules does not exist in a container (#1734) 2025-02-13 11:54:33 -06:00
Evans Mungai 7f2a6d5011 chore: updates to make targets for building binaries (#1733)
* chore: do not automatically clean binaries before building

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

* chore: detect if source files changed before building

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

---------

Signed-off-by: Evans Mungai <evans@replicated.com>
2025-02-13 14:02:27 +00:00
dependabot[bot]andlnx01 7efdb2b59b chore(deps): bump github.com/distribution/distribution/v3 from 3.0.0-rc.2 to 3.0.0-rc.3 in the go_modules group (#1732)
chore(deps): bump github.com/distribution/distribution/v3

Bumps the go_modules group with 1 update: [github.com/distribution/distribution/v3](https://github.com/distribution/distribution).


Updates `github.com/distribution/distribution/v3` from 3.0.0-rc.2 to 3.0.0-rc.3
- [Release notes](https://github.com/distribution/distribution/releases)
- [Commits](https://github.com/distribution/distribution/compare/v3.0.0-rc.2...v3.0.0-rc.3)

---
updated-dependencies:
- dependency-name: github.com/distribution/distribution/v3
  dependency-type: direct:production
  dependency-group: go_modules
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-12 00:23:11 +00:00
Dexter Yan 683391522e fix(window): improve rename file process and remove windows release (#1728) 2025-02-11 17:33:08 +13:00
dependabot[bot]andlnx01 019098a113 chore(deps): bump golang.org/x/net from 0.34.0 to 0.35.0 in the security group (#1731)
chore(deps): bump golang.org/x/net in the security group

Bumps the security group with 1 update: [golang.org/x/net](https://github.com/golang/net).


Updates `golang.org/x/net` from 0.34.0 to 0.35.0
- [Commits](https://github.com/golang/net/compare/v0.34.0...v0.35.0)

---
updated-dependencies:
- 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>
2025-02-11 00:23:04 +00:00
dependabot[bot]andlnx01 f136b1fb24 chore(deps): bump the security group across 1 directory with 8 updates (#1730)
Bumps the security group with 7 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [github.com/cilium/ebpf](https://github.com/cilium/ebpf) | `0.17.1` | `0.17.2` |
| [github.com/containers/image/v5](https://github.com/containers/image) | `5.33.1` | `5.34.0` |
| [github.com/spf13/pflag](https://github.com/spf13/pflag) | `1.0.5` | `1.0.6` |
| [golang.org/x/mod](https://github.com/golang/mod) | `0.22.0` | `0.23.0` |
| [golang.org/x/sync](https://github.com/golang/sync) | `0.10.0` | `0.11.0` |
| [golang.org/x/sys](https://github.com/golang/sys) | `0.29.0` | `0.30.0` |
| [golang.org/x/text](https://github.com/golang/text) | `0.21.0` | `0.22.0` |



Updates `github.com/cilium/ebpf` from 0.17.1 to 0.17.2
- [Release notes](https://github.com/cilium/ebpf/releases)
- [Commits](https://github.com/cilium/ebpf/compare/v0.17.1...v0.17.2)

Updates `github.com/containers/image/v5` from 5.33.1 to 5.34.0
- [Release notes](https://github.com/containers/image/releases)
- [Commits](https://github.com/containers/image/compare/v5.33.1...v5.34.0)

Updates `github.com/spf13/pflag` from 1.0.5 to 1.0.6
- [Release notes](https://github.com/spf13/pflag/releases)
- [Commits](https://github.com/spf13/pflag/compare/v1.0.5...v1.0.6)

Updates `golang.org/x/exp` from 0.0.0-20241108190413-2d47ceb2692f to 0.0.0-20241217172543-b2144cdd0a67
- [Commits](https://github.com/golang/exp/commits)

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

Updates `golang.org/x/sync` from 0.10.0 to 0.11.0
- [Commits](https://github.com/golang/sync/compare/v0.10.0...v0.11.0)

Updates `golang.org/x/sys` from 0.29.0 to 0.30.0
- [Commits](https://github.com/golang/sys/compare/v0.29.0...v0.30.0)

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

---
updated-dependencies:
- dependency-name: github.com/cilium/ebpf
  dependency-type: direct:production
  update-type: version-update:semver-patch
  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: github.com/spf13/pflag
  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
- 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
- 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>
2025-02-10 06:08:13 +00:00
Ash de791e951c Enable Daemonsets in ClusterResources analyzer (#1729) 2025-02-06 13:55:39 -05:00
Gerard Nguyen fa5365cfae fix: [sc-118962] Unable to Retrieve TLS Parameters from Kubernetes Secrets with the Postgres Collector (#1724)
* use Data instead of StringData
2025-01-28 21:39:39 +11:00
dependabot[bot]andlnx01 b9d49d97b6 chore(deps): bump the security group with 2 updates (#1726)
Bumps the security group with 2 updates: [github.com/miekg/dns](https://github.com/miekg/dns) and [sigs.k8s.io/controller-runtime](https://github.com/kubernetes-sigs/controller-runtime).


Updates `github.com/miekg/dns` from 1.1.62 to 1.1.63
- [Changelog](https://github.com/miekg/dns/blob/master/Makefile.release)
- [Commits](https://github.com/miekg/dns/compare/v1.1.62...v1.1.63)

Updates `sigs.k8s.io/controller-runtime` from 0.20.0 to 0.20.1
- [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.20.0...v0.20.1)

---
updated-dependencies:
- dependency-name: github.com/miekg/dns
  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
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-28 00:23:03 +00:00
dependabot[bot]andlnx01 bb7cd5fa8d chore(deps): bump the security group with 16 updates (#1723)
Bumps the security group with 16 updates:

| Package | From | To |
| --- | --- | --- |
| [github.com/containers/image/v5](https://github.com/containers/image) | `5.33.0` | `5.33.1` |
| [github.com/hashicorp/go-getter](https://github.com/hashicorp/go-getter) | `1.7.7` | `1.7.8` |
| [github.com/vmware-tanzu/velero](https://github.com/vmware-tanzu/velero) | `1.15.1` | `1.15.2` |
| [go.opentelemetry.io/otel](https://github.com/open-telemetry/opentelemetry-go) | `1.33.0` | `1.34.0` |
| [go.opentelemetry.io/otel/sdk](https://github.com/open-telemetry/opentelemetry-go) | `1.33.0` | `1.34.0` |
| [k8s.io/api](https://github.com/kubernetes/api) | `0.32.0` | `0.32.1` |
| [k8s.io/apiextensions-apiserver](https://github.com/kubernetes/apiextensions-apiserver) | `0.32.0` | `0.32.1` |
| [k8s.io/apimachinery](https://github.com/kubernetes/apimachinery) | `0.32.0` | `0.32.1` |
| [k8s.io/apiserver](https://github.com/kubernetes/apiserver) | `0.32.0` | `0.32.1` |
| [k8s.io/cli-runtime](https://github.com/kubernetes/cli-runtime) | `0.32.0` | `0.32.1` |
| [k8s.io/client-go](https://github.com/kubernetes/client-go) | `0.32.0` | `0.32.1` |
| [sigs.k8s.io/controller-runtime](https://github.com/kubernetes-sigs/controller-runtime) | `0.19.4` | `0.20.0` |
| [sigs.k8s.io/e2e-framework](https://github.com/kubernetes-sigs/e2e-framework) | `0.5.0` | `0.6.0` |
| [helm.sh/helm/v3](https://github.com/helm/helm) | `3.16.4` | `3.17.0` |
| [k8s.io/kubelet](https://github.com/kubernetes/kubelet) | `0.32.0` | `0.32.1` |
| [k8s.io/metrics](https://github.com/kubernetes/metrics) | `0.32.0` | `0.32.1` |


Updates `github.com/containers/image/v5` from 5.33.0 to 5.33.1
- [Release notes](https://github.com/containers/image/releases)
- [Commits](https://github.com/containers/image/compare/v5.33.0...v5.33.1)

Updates `github.com/hashicorp/go-getter` from 1.7.7 to 1.7.8
- [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.7...v1.7.8)

Updates `github.com/vmware-tanzu/velero` from 1.15.1 to 1.15.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.15.1...v1.15.2)

Updates `go.opentelemetry.io/otel` from 1.33.0 to 1.34.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.33.0...v1.34.0)

Updates `go.opentelemetry.io/otel/sdk` from 1.33.0 to 1.34.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.33.0...v1.34.0)

Updates `k8s.io/api` from 0.32.0 to 0.32.1
- [Commits](https://github.com/kubernetes/api/compare/v0.32.0...v0.32.1)

Updates `k8s.io/apiextensions-apiserver` from 0.32.0 to 0.32.1
- [Release notes](https://github.com/kubernetes/apiextensions-apiserver/releases)
- [Commits](https://github.com/kubernetes/apiextensions-apiserver/compare/v0.32.0...v0.32.1)

Updates `k8s.io/apimachinery` from 0.32.0 to 0.32.1
- [Commits](https://github.com/kubernetes/apimachinery/compare/v0.32.0...v0.32.1)

Updates `k8s.io/apiserver` from 0.32.0 to 0.32.1
- [Commits](https://github.com/kubernetes/apiserver/compare/v0.32.0...v0.32.1)

Updates `k8s.io/cli-runtime` from 0.32.0 to 0.32.1
- [Commits](https://github.com/kubernetes/cli-runtime/compare/v0.32.0...v0.32.1)

Updates `k8s.io/client-go` from 0.32.0 to 0.32.1
- [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kubernetes/client-go/compare/v0.32.0...v0.32.1)

Updates `sigs.k8s.io/controller-runtime` from 0.19.4 to 0.20.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.19.4...v0.20.0)

Updates `sigs.k8s.io/e2e-framework` from 0.5.0 to 0.6.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.5.0...v0.6.0)

Updates `helm.sh/helm/v3` from 3.16.4 to 3.17.0
- [Release notes](https://github.com/helm/helm/releases)
- [Commits](https://github.com/helm/helm/compare/v3.16.4...v3.17.0)

Updates `k8s.io/kubelet` from 0.32.0 to 0.32.1
- [Commits](https://github.com/kubernetes/kubelet/compare/v0.32.0...v0.32.1)

Updates `k8s.io/metrics` from 0.32.0 to 0.32.1
- [Commits](https://github.com/kubernetes/metrics/compare/v0.32.0...v0.32.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: 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: 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-minor
  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: 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>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-21 00:22:48 +00:00
dependabot[bot]andlnx01 f97c66de9a chore(deps): bump helm.sh/helm/v3 from 3.16.4 to 3.17.0 in /examples/sdk/helm-template in the security group (#1722)
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.16.4 to 3.17.0
- [Release notes](https://github.com/helm/helm/releases)
- [Commits](https://github.com/helm/helm/compare/v3.16.4...v3.17.0)

---
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>
2025-01-21 00:22:16 +00:00
dependabot[bot]andlnx01 58e71d1a99 chore(deps): bump the security group with 3 updates (#1721)
Bumps the security group with 3 updates: [github.com/hashicorp/go-getter](https://github.com/hashicorp/go-getter), [sigs.k8s.io/controller-runtime](https://github.com/kubernetes-sigs/controller-runtime) and [periph.io/x/host/v3](https://github.com/periph/host).


Updates `github.com/hashicorp/go-getter` from 1.7.6 to 1.7.7
- [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.6...v1.7.7)

Updates `sigs.k8s.io/controller-runtime` from 0.19.3 to 0.19.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.19.3...v0.19.4)

Updates `periph.io/x/host/v3` from 3.8.2 to 3.8.3
- [Release notes](https://github.com/periph/host/releases)
- [Commits](https://github.com/periph/host/compare/v3.8.2...v3.8.3)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/go-getter
  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: periph.io/x/host/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>
2025-01-14 00:22:49 +00:00
Gerard Nguyen 7a00dbea05 fix: [sc-116508] [Troubleshoot] support-bundle load-spec from URI field logic is fragile (#1716)
do not load invalid URI
2025-01-08 09:03:32 +11:00
dependabot[bot]andlnx01 4e105657d4 chore(deps): bump the security group with 2 updates (#1718)
Bumps the security group with 2 updates: [golang.org/x/net](https://github.com/golang/net) and [golang.org/x/sys](https://github.com/golang/sys).


Updates `golang.org/x/net` from 0.33.0 to 0.34.0
- [Commits](https://github.com/golang/net/compare/v0.33.0...v0.34.0)

Updates `golang.org/x/sys` from 0.28.0 to 0.29.0
- [Commits](https://github.com/golang/sys/compare/v0.28.0...v0.29.0)

---
updated-dependencies:
- 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
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-07 00:23:49 +00:00
Xav Paice 86b7e54466 Revert "feat: save YAML spec used to generate support bundle/preflight" (#1715)
Revert "feat: save YAML spec used to generate support bundle/preflight (#1713)"

This reverts commit f6f51acbd5.
2025-01-06 09:42:58 +11:00
Gerard Nguyen f6f51acbd5 feat: save YAML spec used to generate support bundle/preflight (#1713)
* save YAML spec of support bundle

* save YAML spec of preflight

* add unit test

* redact TLS private key by default in output spec

* update YAML path for HTTP TLS redactor
2025-01-04 11:35:43 +11:00
Dexter YanandEvans Mungai 64ee9e5596 feat(nodeResources): add GPU support (#1708)
* feat(nodeResources): add GPU support

* add resourceCapacity and sum test

* update with make schemas

* Correct tests names

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

---------

Signed-off-by: Evans Mungai <evans@replicated.com>
Co-authored-by: Evans Mungai <evans@replicated.com>
2025-01-03 15:11:10 +13:00
Dexter Yan 277272249b fix: upgrade go version to 1.23.0 for helm-template (#1712) 2024-12-31 14:35:39 +13:00
dependabot[bot]andlnx01 607124381c chore(deps): bump github.com/distribution/distribution/v3 from 3.0.0-rc.1 to 3.0.0-rc.2 (#1711)
chore(deps): bump github.com/distribution/distribution/v3

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

---
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-12-31 00:23:32 +00:00
dependabot[bot]andlnx01 b9b20753e9 chore(deps): bump github.com/vmware-tanzu/velero from 1.15.0 to 1.15.1 in the security group (#1710)
chore(deps): bump github.com/vmware-tanzu/velero in the security group

Bumps the security group with 1 update: [github.com/vmware-tanzu/velero](https://github.com/vmware-tanzu/velero).


Updates `github.com/vmware-tanzu/velero` from 1.15.0 to 1.15.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.15.0...v1.15.1)

---
updated-dependencies:
- dependency-name: github.com/vmware-tanzu/velero
  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-12-31 00:23:04 +00:00
3f1314c00d chore(deps): bump the security group across 1 directory with 17 updates (#1709)
* chore(deps): bump the security group across 1 directory with 17 updates

Bumps the security group with 13 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [github.com/cilium/ebpf](https://github.com/cilium/ebpf) | `0.16.0` | `0.17.1` |
| [github.com/containerd/cgroups/v3](https://github.com/containerd/cgroups) | `3.0.4` | `3.0.5` |
| [github.com/jackc/pgx/v5](https://github.com/jackc/pgx) | `5.7.1` | `5.7.2` |
| [github.com/microsoft/go-mssqldb](https://github.com/microsoft/go-mssqldb) | `1.7.2` | `1.8.0` |
| [go.opentelemetry.io/otel](https://github.com/open-telemetry/opentelemetry-go) | `1.32.0` | `1.33.0` |
| [go.opentelemetry.io/otel/sdk](https://github.com/open-telemetry/opentelemetry-go) | `1.32.0` | `1.33.0` |
| [k8s.io/api](https://github.com/kubernetes/api) | `0.31.3` | `0.32.0` |
| [k8s.io/apiextensions-apiserver](https://github.com/kubernetes/apiextensions-apiserver) | `0.31.3` | `0.32.0` |
| [k8s.io/cli-runtime](https://github.com/kubernetes/cli-runtime) | `0.31.3` | `0.32.0` |
| [golang.org/x/net](https://github.com/golang/net) | `0.31.0` | `0.33.0` |
| [helm.sh/helm/v3](https://github.com/helm/helm) | `3.16.3` | `3.16.4` |
| [k8s.io/kubelet](https://github.com/kubernetes/kubelet) | `0.31.3` | `0.32.0` |
| [k8s.io/metrics](https://github.com/kubernetes/metrics) | `0.31.3` | `0.32.0` |



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

Updates `github.com/containerd/cgroups/v3` from 3.0.4 to 3.0.5
- [Release notes](https://github.com/containerd/cgroups/releases)
- [Commits](https://github.com/containerd/cgroups/compare/v3.0.4...v3.0.5)

Updates `github.com/jackc/pgx/v5` from 5.7.1 to 5.7.2
- [Changelog](https://github.com/jackc/pgx/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jackc/pgx/compare/v5.7.1...v5.7.2)

Updates `github.com/microsoft/go-mssqldb` from 1.7.2 to 1.8.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.7.2...v1.8.0)

Updates `go.opentelemetry.io/otel` from 1.32.0 to 1.33.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.32.0...v1.33.0)

Updates `go.opentelemetry.io/otel/sdk` from 1.32.0 to 1.33.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.32.0...v1.33.0)

Updates `k8s.io/api` from 0.31.3 to 0.32.0
- [Commits](https://github.com/kubernetes/api/compare/v0.31.3...v0.32.0)

Updates `k8s.io/apiextensions-apiserver` from 0.31.3 to 0.32.0
- [Release notes](https://github.com/kubernetes/apiextensions-apiserver/releases)
- [Commits](https://github.com/kubernetes/apiextensions-apiserver/compare/v0.31.3...v0.32.0)

Updates `k8s.io/apimachinery` from 0.31.3 to 0.32.0
- [Commits](https://github.com/kubernetes/apimachinery/compare/v0.31.3...v0.32.0)

Updates `k8s.io/apiserver` from 0.31.3 to 0.32.0
- [Commits](https://github.com/kubernetes/apiserver/compare/v0.31.3...v0.32.0)

Updates `k8s.io/cli-runtime` from 0.31.3 to 0.32.0
- [Commits](https://github.com/kubernetes/cli-runtime/compare/v0.31.3...v0.32.0)

Updates `k8s.io/client-go` from 0.31.3 to 0.32.0
- [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kubernetes/client-go/compare/v0.31.3...v0.32.0)

Updates `golang.org/x/net` from 0.31.0 to 0.33.0
- [Commits](https://github.com/golang/net/compare/v0.31.0...v0.33.0)

Updates `helm.sh/helm/v3` from 3.16.3 to 3.16.4
- [Release notes](https://github.com/helm/helm/releases)
- [Commits](https://github.com/helm/helm/compare/v3.16.3...v3.16.4)

Updates `k8s.io/kubelet` from 0.31.3 to 0.32.0
- [Commits](https://github.com/kubernetes/kubelet/compare/v0.31.3...v0.32.0)

Updates `k8s.io/metrics` from 0.31.3 to 0.32.0
- [Commits](https://github.com/kubernetes/metrics/compare/v0.31.3...v0.32.0)

Updates `k8s.io/utils` from 0.0.0-20240711033017-18e509b52bc8 to 0.0.0-20241104100929-3ea5e8cea738
- [Commits](https://github.com/kubernetes/utils/commits)

---
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/containerd/cgroups/v3
  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-patch
  dependency-group: security
- 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
- dependency-name: k8s.io/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: k8s.io/apiextensions-apiserver
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: k8s.io/apimachinery
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: k8s.io/apiserver
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: k8s.io/cli-runtime
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: k8s.io/client-go
  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: 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-minor
  dependency-group: security
- dependency-name: k8s.io/metrics
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: k8s.io/utils
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
...

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

* upgrade go version 1.23.0

* make schemas

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Dexter Yan <yanshaocong@gmail.com>
2024-12-30 17:25:11 +13:00
dependabot[bot]andlnx01 fcfdc63634 chore(deps): bump golang.org/x/crypto from 0.29.0 to 0.31.0 in the go_modules group (#1705)
chore(deps): bump golang.org/x/crypto in the go_modules group

Bumps the go_modules group with 1 update: [golang.org/x/crypto](https://github.com/golang/crypto).


Updates `golang.org/x/crypto` from 0.29.0 to 0.31.0
- [Commits](https://github.com/golang/crypto/compare/v0.29.0...v0.31.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-17 06:08:34 +00:00
dependabot[bot]andlnx01 d67cdb7b90 chore(deps): bump helm.sh/helm/v3 from 3.16.3 to 3.16.4 in /examples/sdk/helm-template in the security group (#1704)
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.16.3 to 3.16.4
- [Release notes](https://github.com/helm/helm/releases)
- [Commits](https://github.com/helm/helm/compare/v3.16.3...v3.16.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-12-17 00:25:25 +00:00
Gerard Nguyen a6fbf144b8 feat: container statuses analyzer (#1698)
* new schema for analyzer ClusterContainerStatues
2024-12-04 10:36:23 +11:00
dependabot[bot]andlnx01 b38a6a0389 chore(deps): bump sigs.k8s.io/controller-runtime from 0.19.2 to 0.19.3 in the security group (#1702)
chore(deps): bump sigs.k8s.io/controller-runtime in the security group

Bumps the security group with 1 update: [sigs.k8s.io/controller-runtime](https://github.com/kubernetes-sigs/controller-runtime).


Updates `sigs.k8s.io/controller-runtime` from 0.19.2 to 0.19.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.19.2...v0.19.3)

---
updated-dependencies:
- dependency-name: sigs.k8s.io/controller-runtime
  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-12-03 00:25:53 +00:00
Dexter Yan de15d02f39 fix(make): improve generate cmd for go mod (#1699) 2024-12-02 18:27:33 +13:00
Miguel Varela Ramos 8e2647077d feat: add support for matchExpressions when filtering for nodes (#1697)
* feat: add support for matchExpressions when filtering for nodes

* fix: make generate
2024-11-30 23:15:26 +11:00
dependabot[bot]andlnx01 6e5db6d895 chore(deps): bump the security group with 12 updates (#1696)
Bumps the security group with 12 updates:

| Package | From | To |
| --- | --- | --- |
| [github.com/containerd/cgroups/v3](https://github.com/containerd/cgroups) | `3.0.3` | `3.0.4` |
| [github.com/stretchr/testify](https://github.com/stretchr/testify) | `1.9.0` | `1.10.0` |
| [golang.org/x/exp](https://github.com/golang/exp) | `0.0.0-20241009180824-f66d83c29e7c` | `0.0.0-20241108190413-2d47ceb2692f` |
| [k8s.io/api](https://github.com/kubernetes/api) | `0.31.2` | `0.31.3` |
| [k8s.io/apiextensions-apiserver](https://github.com/kubernetes/apiextensions-apiserver) | `0.31.2` | `0.31.3` |
| [k8s.io/apimachinery](https://github.com/kubernetes/apimachinery) | `0.31.2` | `0.31.3` |
| [k8s.io/apiserver](https://github.com/kubernetes/apiserver) | `0.31.2` | `0.31.3` |
| [k8s.io/cli-runtime](https://github.com/kubernetes/cli-runtime) | `0.31.2` | `0.31.3` |
| [k8s.io/client-go](https://github.com/kubernetes/client-go) | `0.31.2` | `0.31.3` |
| [sigs.k8s.io/controller-runtime](https://github.com/kubernetes-sigs/controller-runtime) | `0.19.1` | `0.19.2` |
| [k8s.io/kubelet](https://github.com/kubernetes/kubelet) | `0.31.2` | `0.31.3` |
| [k8s.io/metrics](https://github.com/kubernetes/metrics) | `0.31.2` | `0.31.3` |


Updates `github.com/containerd/cgroups/v3` from 3.0.3 to 3.0.4
- [Release notes](https://github.com/containerd/cgroups/releases)
- [Commits](https://github.com/containerd/cgroups/compare/v3.0.3...v3.0.4)

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

Updates `golang.org/x/exp` from 0.0.0-20241009180824-f66d83c29e7c to 0.0.0-20241108190413-2d47ceb2692f
- [Commits](https://github.com/golang/exp/commits)

Updates `k8s.io/api` from 0.31.2 to 0.31.3
- [Commits](https://github.com/kubernetes/api/compare/v0.31.2...v0.31.3)

Updates `k8s.io/apiextensions-apiserver` from 0.31.2 to 0.31.3
- [Release notes](https://github.com/kubernetes/apiextensions-apiserver/releases)
- [Commits](https://github.com/kubernetes/apiextensions-apiserver/compare/v0.31.2...v0.31.3)

Updates `k8s.io/apimachinery` from 0.31.2 to 0.31.3
- [Commits](https://github.com/kubernetes/apimachinery/compare/v0.31.2...v0.31.3)

Updates `k8s.io/apiserver` from 0.31.2 to 0.31.3
- [Commits](https://github.com/kubernetes/apiserver/compare/v0.31.2...v0.31.3)

Updates `k8s.io/cli-runtime` from 0.31.2 to 0.31.3
- [Commits](https://github.com/kubernetes/cli-runtime/compare/v0.31.2...v0.31.3)

Updates `k8s.io/client-go` from 0.31.2 to 0.31.3
- [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kubernetes/client-go/compare/v0.31.2...v0.31.3)

Updates `sigs.k8s.io/controller-runtime` from 0.19.1 to 0.19.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.19.1...v0.19.2)

Updates `k8s.io/kubelet` from 0.31.2 to 0.31.3
- [Commits](https://github.com/kubernetes/kubelet/compare/v0.31.2...v0.31.3)

Updates `k8s.io/metrics` from 0.31.2 to 0.31.3
- [Commits](https://github.com/kubernetes/metrics/compare/v0.31.2...v0.31.3)

---
updated-dependencies:
- dependency-name: github.com/containerd/cgroups/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/exp
  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: 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-11-26 00:24:27 +00:00
Ash ecc92b1e3e [bug] Quick fix for handling non 200 status codes when loading specs from URI (#1695)
* Quick fix for handling non 200 status codes when loading specs from URI

Go http client already handles 3xx responses for us

* note
2024-11-25 15:04:38 +00:00
Ricardo Maraschini 9f5f0633cf feat: rename templating variables (#1693)
when templating the output of the namespace connectivity check we were
referring to the 'fromCIDR' as 'fromNamespace'. it makes way more sense
to refer to it as 'fromCIDR' as this is how it is provided in the input
for the collector.

as this is a brand new feature it is very unlikely that anyone is using
this feature (except for the embedded cluster that still needs to be
patched accodringly).

this is how the analyser were defined before:

```yaml
apiVersion: troubleshoot.sh/v1beta2
kind: HostPreflight
metadata:
    name: ec-cluster-preflight
spec:
    analyzers:
        - networkNamespaceConnectivity:
            collectorName: check-network-connectivity
            outcomes:
            - pass:
                message: "Communication between {{ .FromNamespace }} and {{ .ToNamespace }} is working"
            - fail:
                message: "{{ .ErrorMessage }}"
```

and this is how it is now:

```yaml
apiVersion: troubleshoot.sh/v1beta2
kind: HostPreflight
metadata:
    name: ec-cluster-preflight
spec:
    analyzers:
        - networkNamespaceConnectivity:
            collectorName: check-network-connectivity
            outcomes:
            - pass:
                message: "Communication between {{ .FromCIDR }} and {{ .ToCIDR }} is working"
            - fail:
                message: "{{ .ErrorMessage }}"

```
2024-11-21 16:03:50 +01:00
Dexter Yan 6167fd8a5e fix(collector): fix dns collector limited to 63 chars (#1690) 2024-11-19 17:47:24 +13:00
91bf0242d4 chore(deps): bump the security group with 12 updates (#1683)
* chore(deps): bump the security group with 12 updates

Bumps the security group with 12 updates:

| Package | From | To |
| --- | --- | --- |
| [github.com/containers/image/v5](https://github.com/containers/image) | `5.32.2` | `5.33.0` |
| [github.com/vishvananda/netlink](https://github.com/vishvananda/netlink) | `1.2.1-beta.2` | `1.3.0` |
| [github.com/vishvananda/netns](https://github.com/vishvananda/netns) | `0.0.4` | `0.0.5` |
| [github.com/vmware-tanzu/velero](https://github.com/vmware-tanzu/velero) | `1.14.1` | `1.15.0` |
| [go.opentelemetry.io/otel](https://github.com/open-telemetry/opentelemetry-go) | `1.31.0` | `1.32.0` |
| [go.opentelemetry.io/otel/sdk](https://github.com/open-telemetry/opentelemetry-go) | `1.31.0` | `1.32.0` |
| [golang.org/x/exp](https://github.com/golang/exp) | `0.0.0-20240613232115-7f521ea00fb8` | `0.0.0-20241009180824-f66d83c29e7c` |
| [golang.org/x/mod](https://github.com/golang/mod) | `0.21.0` | `0.22.0` |
| [golang.org/x/sync](https://github.com/golang/sync) | `0.8.0` | `0.9.0` |
| [golang.org/x/net](https://github.com/golang/net) | `0.30.0` | `0.31.0` |
| [golang.org/x/sys](https://github.com/golang/sys) | `0.26.0` | `0.27.0` |
| [golang.org/x/text](https://github.com/golang/text) | `0.19.0` | `0.20.0` |


Updates `github.com/containers/image/v5` from 5.32.2 to 5.33.0
- [Release notes](https://github.com/containers/image/releases)
- [Commits](https://github.com/containers/image/compare/v5.32.2...v5.33.0)

Updates `github.com/vishvananda/netlink` from 1.2.1-beta.2 to 1.3.0
- [Release notes](https://github.com/vishvananda/netlink/releases)
- [Commits](https://github.com/vishvananda/netlink/compare/v1.2.1-beta.2...v1.3.0)

Updates `github.com/vishvananda/netns` from 0.0.4 to 0.0.5
- [Release notes](https://github.com/vishvananda/netns/releases)
- [Commits](https://github.com/vishvananda/netns/compare/v0.0.4...v0.0.5)

Updates `github.com/vmware-tanzu/velero` from 1.14.1 to 1.15.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.14.1...v1.15.0)

Updates `go.opentelemetry.io/otel` from 1.31.0 to 1.32.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.31.0...v1.32.0)

Updates `go.opentelemetry.io/otel/sdk` from 1.31.0 to 1.32.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.31.0...v1.32.0)

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

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

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

Updates `golang.org/x/net` from 0.30.0 to 0.31.0
- [Commits](https://github.com/golang/net/compare/v0.30.0...v0.31.0)

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

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

---
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/vishvananda/netlink
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: github.com/vishvananda/netns
  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: 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: 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/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>

* upgrade go version

* fix go sum merge

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Dexter Yan <yanshaocong@gmail.com>
2024-11-19 16:06:21 +13:00
dependabot[bot]andlnx01 5a820c02ff chore(deps): bump helm.sh/helm/v3 from 3.16.2 to 3.16.3 in /examples/sdk/helm-template in the security group (#1692)
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.16.2 to 3.16.3
- [Release notes](https://github.com/helm/helm/releases)
- [Commits](https://github.com/helm/helm/compare/v3.16.2...v3.16.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-11-19 00:24:47 +00:00
dependabot[bot]andlnx01 cf10bd0e82 chore(deps): bump the security group with 13 updates (#1691)
Bumps the security group with 13 updates:

| Package | From | To |
| --- | --- | --- |
| [github.com/containers/image/v5](https://github.com/containers/image) | `5.32.2` | `5.33.0` |
| [github.com/vishvananda/netlink](https://github.com/vishvananda/netlink) | `1.2.1-beta.2` | `1.3.0` |
| [github.com/vishvananda/netns](https://github.com/vishvananda/netns) | `0.0.4` | `0.0.5` |
| [github.com/vmware-tanzu/velero](https://github.com/vmware-tanzu/velero) | `1.14.1` | `1.15.0` |
| [go.opentelemetry.io/otel](https://github.com/open-telemetry/opentelemetry-go) | `1.31.0` | `1.32.0` |
| [go.opentelemetry.io/otel/sdk](https://github.com/open-telemetry/opentelemetry-go) | `1.31.0` | `1.32.0` |
| [golang.org/x/exp](https://github.com/golang/exp) | `0.0.0-20240613232115-7f521ea00fb8` | `0.0.0-20241009180824-f66d83c29e7c` |
| [golang.org/x/mod](https://github.com/golang/mod) | `0.21.0` | `0.22.0` |
| [golang.org/x/sync](https://github.com/golang/sync) | `0.8.0` | `0.9.0` |
| [golang.org/x/net](https://github.com/golang/net) | `0.30.0` | `0.31.0` |
| [golang.org/x/sys](https://github.com/golang/sys) | `0.26.0` | `0.27.0` |
| [golang.org/x/text](https://github.com/golang/text) | `0.19.0` | `0.20.0` |
| [helm.sh/helm/v3](https://github.com/helm/helm) | `3.16.2` | `3.16.3` |


Updates `github.com/containers/image/v5` from 5.32.2 to 5.33.0
- [Release notes](https://github.com/containers/image/releases)
- [Commits](https://github.com/containers/image/compare/v5.32.2...v5.33.0)

Updates `github.com/vishvananda/netlink` from 1.2.1-beta.2 to 1.3.0
- [Release notes](https://github.com/vishvananda/netlink/releases)
- [Commits](https://github.com/vishvananda/netlink/compare/v1.2.1-beta.2...v1.3.0)

Updates `github.com/vishvananda/netns` from 0.0.4 to 0.0.5
- [Release notes](https://github.com/vishvananda/netns/releases)
- [Commits](https://github.com/vishvananda/netns/compare/v0.0.4...v0.0.5)

Updates `github.com/vmware-tanzu/velero` from 1.14.1 to 1.15.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.14.1...v1.15.0)

Updates `go.opentelemetry.io/otel` from 1.31.0 to 1.32.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.31.0...v1.32.0)

Updates `go.opentelemetry.io/otel/sdk` from 1.31.0 to 1.32.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.31.0...v1.32.0)

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

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

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

Updates `golang.org/x/net` from 0.30.0 to 0.31.0
- [Commits](https://github.com/golang/net/compare/v0.30.0...v0.31.0)

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

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

Updates `helm.sh/helm/v3` from 3.16.2 to 3.16.3
- [Release notes](https://github.com/helm/helm/releases)
- [Commits](https://github.com/helm/helm/compare/v3.16.2...v3.16.3)

---
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/vishvananda/netlink
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: github.com/vishvananda/netns
  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: 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: 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/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
- 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-11-19 00:24:21 +00:00
Gerard Nguyen 7bb88e6b83 feat: ensure Copy collector run last (#1688)
* ensure Copy collector run last

* * add unit test
* reorder in Preflight as well
2024-11-15 10:59:38 +11:00
dependabot[bot]andlnx01 be2c2128c6 chore(deps): bump rajatjindal/krew-release-bot from 0.0.46 to 0.0.47 (#1685)
Bumps [rajatjindal/krew-release-bot](https://github.com/rajatjindal/krew-release-bot) from 0.0.46 to 0.0.47.
- [Release notes](https://github.com/rajatjindal/krew-release-bot/releases)
- [Changelog](https://github.com/rajatjindal/krew-release-bot/blob/main/.goreleaser.yml)
- [Commits](https://github.com/rajatjindal/krew-release-bot/compare/v0.0.46...v0.0.47)

---
updated-dependencies:
- dependency-name: rajatjindal/krew-release-bot
  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-11-13 16:41:15 +13:00
Dexter Yan 9ef117f080 upgrade go version to 1.22.8 (#1689) 2024-11-13 16:40:37 +13:00
Dexter Yan 1a828fa90b fix(analyzer): add missing warning in outcome (#1687) 2024-11-13 16:32:54 +13:00
Gerard Nguyen 9970fb1371 feat: [sc-114709] [troubleshoot] gracefully handle inability to load specs if multiple specs provided (#1686)
gracefully handle unable to load URL spec
2024-11-13 10:01:32 +13:00
dependabot[bot]andlnx01 0213fbb124 chore(deps): bump github.com/distribution/distribution/v3 from 3.0.0-beta.1 to 3.0.0-rc.1 (#1684)
chore(deps): bump github.com/distribution/distribution/v3

Bumps [github.com/distribution/distribution/v3](https://github.com/distribution/distribution) from 3.0.0-beta.1 to 3.0.0-rc.1.
- [Release notes](https://github.com/distribution/distribution/releases)
- [Commits](https://github.com/distribution/distribution/compare/v3.0.0-beta.1...v3.0.0-rc.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-11-12 00:22:43 +00:00
deeeea7cec exec remote host collectors in a daemonset (#1671)
Co-authored-by: Gerard Nguyen <gerard@replicated.com>
Co-authored-by: Dexter Yan <yanshaocong@gmail.com>
2024-11-12 08:47:24 +13:00
João Antunes 197f6de425 feat(host_analyzer): add host sysctl analyzer (#1681)
* feat(host_analyzer): add host sysctl analyzer

* chore: add e2e tests to support bundle collection

* chore: missing spec e2e test update

* chore: cleanup remote collector and use parse operator

* chore: update schemas
2024-11-08 18:55:24 +00:00
Xav PaiceandDexter Yan 2f62240ed3 remove redundant tests (#1677)
* remove redundant tests

* fix workflow syntax error

* fix workflow syntax error

* fix k3s version for tests

* fix k3s version for tests

* f

* add vet to test-integration

---------

Co-authored-by: Dexter Yan <yanshaocong@gmail.com>
2024-11-08 10:54:26 +00:00
Dexter Yan 40eef3cdc8 feat(e2e): add local host support bundle test (#1680) 2024-11-08 17:14:06 +13:00
Evans MungaiandDexter Yan d25aa7d0ea fix: Do not fail analysis if node list does not exist (#1678)
* fix: Do not error if node list does not exist

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

* fix test fail

---------

Signed-off-by: Evans Mungai <evans@replicated.com>
Co-authored-by: Dexter Yan <yanshaocong@gmail.com>
2024-11-08 09:53:03 +13:00
João AntunesandEvans Mungai 77c9968ff6 feat(host_sysctl): add host sysctl collector (#1676)
* feat(host_sysctl): add host sysctl collector

* chore: add examples

* Update pkg/collect/host_sysctl.go

Co-authored-by: Evans Mungai <evans@replicated.com>

* chore: use sysctl package vs exec calls

* chore: make linter happy

* chore: make schemas

* chore: go back to sysctl exec

* chore: make linter happy

---------

Co-authored-by: Evans Mungai <evans@replicated.com>
2024-11-07 18:18:11 +00:00
Diamon Wiggins 06506ed95d Fix remote host collection RBAC checks (#1672)
* fix remote host collection rbac checks

* move saveNodeList into collectRemoteHost function

* fix resource attribute list and retrieve namespace from kubeconfig

* revert change to set a default namespace from kubeconfig

* remove duplicate code
2024-11-07 10:07:27 -05:00
Ricardo Maraschini e272683bce feat: implement collector and analyser for network namespace connectivity (#1670)
* feat: implement collector and analyser for network namespace connectivity

checks if two network namespaces can talk to each other on udp and tcp.
its usage is as follows:

```yaml
apiVersion: troubleshoot.sh/v1beta2
kind: SupportBundle
metadata:
  name: test
spec:
  hostCollectors:
  - networkNamespaceConnectivity:
      collectorName: check-network-connectivity
      fromCIDR: 10.0.0.0/24
      toCIDR: 10.0.1.0/24
  hostAnalyzers:
  - networkNamespaceConnectivity:
      collectorName: check-network-connectivity
      outcomes:
      - pass:
          message: "Communication between 10.0.0.0/24 and 10.0.1.0/24 is working"
      - fail:
          message: "Communication between 10.0.0.0/24 and 10.0.1.0/24 isn't working"
```

if this fails then you may need to enable `forwarding` with:

```bash
sysctl -w net.ipv4.ip_forward=1
```

if it still fails then you may need to configure firewalld to allow the
traffic or simply disable it for sake of testing.

* chore: rebuild schemas

* chore: remove unused property

* chore: disable namespaces for other platforms

* chore: make sure we timeout temporary servers

* feat: analyzer now supports multi-node collection

* feat: check both udp and tcp even on failure

check both protocols even if one fails. this pr commit also introduces a
timeout that can be set by the user.

* feat: add templating to the failure outcome

allow users to dump the errors found during the analysis.

* chore: addressing pr comments

* feat: delete interface pair before namespace

even though the interface pair is deleted everyttime we delete the
namespace on my tests we better delete it before we delete the
namespace.

this comes out of a review comment where some people seem to still be
able to see the interface pair even after the namespace is deleted.

i.e. better safe than sorry.

* chore: fix typo on comment
2024-11-06 11:30:13 +01:00
AshandGerard Nguyen ea900a1881 chore: Refactor host cpu analyzer for remote collection (#1664)
* Refactor host cpu analyzer for remote collection

---------

Co-authored-by: Gerard Nguyen <gerard@replicated.com>
2024-11-06 14:43:27 +11:00
Gerard NguyenandDiamon Wiggins f0b8de68ae feat: multiple nodes analyzers (#1667)
* implement refactor for multiple node analyzers

---------

Co-authored-by: Diamon Wiggins <38189728+diamonwiggins@users.noreply.github.com>
2024-11-04 14:17:39 +11:00
AshandEvans Mungai 544a700062 [sc-114813] copy HostCollector fails to copy binary files when run in cluster (#1669)
* Don't convert output bytes to string

This prevents binary files getting mangled when the collector ourput is being passed around between functions

* Update pkg/collect/runner.go

Co-authored-by: Evans Mungai <evans@replicated.com>

* organise imports

---------

Co-authored-by: Evans Mungai <evans@replicated.com>
2024-10-31 10:44:35 +00:00
Dexter Yan 059b5d14d2 fix(collector): limit run pod collector to delete only one related secret (#1668)
* fix(collector): limit run pod collector to delete only related secret

* change to ctx
2024-10-30 14:19:30 +00:00
dependabot[bot]andlnx01 b33d5538e9 chore(deps): bump the security group with 11 updates (#1665)
Bumps the security group with 11 updates:

| Package | From | To |
| --- | --- | --- |
| [github.com/fatih/color](https://github.com/fatih/color) | `1.17.0` | `1.18.0` |
| [k8s.io/api](https://github.com/kubernetes/api) | `0.31.1` | `0.31.2` |
| [k8s.io/apiextensions-apiserver](https://github.com/kubernetes/apiextensions-apiserver) | `0.31.1` | `0.31.2` |
| [k8s.io/apimachinery](https://github.com/kubernetes/apimachinery) | `0.31.1` | `0.31.2` |
| [k8s.io/apiserver](https://github.com/kubernetes/apiserver) | `0.31.1` | `0.31.2` |
| [k8s.io/cli-runtime](https://github.com/kubernetes/cli-runtime) | `0.31.1` | `0.31.2` |
| [k8s.io/client-go](https://github.com/kubernetes/client-go) | `0.31.1` | `0.31.2` |
| [sigs.k8s.io/controller-runtime](https://github.com/kubernetes-sigs/controller-runtime) | `0.19.0` | `0.19.1` |
| [sigs.k8s.io/e2e-framework](https://github.com/kubernetes-sigs/e2e-framework) | `0.4.0` | `0.5.0` |
| [k8s.io/kubelet](https://github.com/kubernetes/kubelet) | `0.31.1` | `0.31.2` |
| [k8s.io/metrics](https://github.com/kubernetes/metrics) | `0.31.1` | `0.31.2` |


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

Updates `k8s.io/api` from 0.31.1 to 0.31.2
- [Commits](https://github.com/kubernetes/api/compare/v0.31.1...v0.31.2)

Updates `k8s.io/apiextensions-apiserver` from 0.31.1 to 0.31.2
- [Release notes](https://github.com/kubernetes/apiextensions-apiserver/releases)
- [Commits](https://github.com/kubernetes/apiextensions-apiserver/compare/v0.31.1...v0.31.2)

Updates `k8s.io/apimachinery` from 0.31.1 to 0.31.2
- [Commits](https://github.com/kubernetes/apimachinery/compare/v0.31.1...v0.31.2)

Updates `k8s.io/apiserver` from 0.31.1 to 0.31.2
- [Commits](https://github.com/kubernetes/apiserver/compare/v0.31.1...v0.31.2)

Updates `k8s.io/cli-runtime` from 0.31.1 to 0.31.2
- [Commits](https://github.com/kubernetes/cli-runtime/compare/v0.31.1...v0.31.2)

Updates `k8s.io/client-go` from 0.31.1 to 0.31.2
- [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kubernetes/client-go/compare/v0.31.1...v0.31.2)

Updates `sigs.k8s.io/controller-runtime` from 0.19.0 to 0.19.1
- [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.19.0...v0.19.1)

Updates `sigs.k8s.io/e2e-framework` from 0.4.0 to 0.5.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.4.0...v0.5.0)

Updates `k8s.io/kubelet` from 0.31.1 to 0.31.2
- [Commits](https://github.com/kubernetes/kubelet/compare/v0.31.1...v0.31.2)

Updates `k8s.io/metrics` from 0.31.1 to 0.31.2
- [Commits](https://github.com/kubernetes/metrics/compare/v0.31.1...v0.31.2)

---
updated-dependencies:
- dependency-name: github.com/fatih/color
  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: 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: 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-10-29 06:08:07 +00:00
Evans Mungai deda4ce98c feat: Do not prompt users to save support bundle analysis results (#1662)
In interactive mode, do not prompt users to save support
bundle analysis results. Users end up providing this file
instead of the support bundle archive. The analysis results
are contained in the support bundle archive already

Signed-off-by: Evans Mungai <evans@replicated.com>
2024-10-25 13:03:16 +01:00
Dexter Yan 350418c6e9 feat(host-collector): add progress for host collector (#1659) 2024-10-25 15:34:09 +13:00
ada mancini eacff7112f support adding a CA cert to http collector (#1624)
* add a TLS parameter for cacert

* pass a ca cert into http request

* test preflight

* make schemas

* log extra information from http request

* pass a proxy into the collector spec

* hitting a segfault; breakpoint

* accept a dir, file, or a string-literal as CA

* move tls params into get, put, post methods

* test for cert untrusted response

* make generate

* make schemas

* more test cases

* make schemas

* dont include system certs

* make generate && make schemas

* resolve gosec G402 warning

* remove old check for system certs

* ignore errcheck "return value not checked" linter errors
2024-10-23 18:15:08 -04:00
Ricardo MaraschiniandEvans Mungai 7ed2f4bff2 feat: Handle failure to load cluster specs gracefully in support-bundle command (#1660)
* feat: Handle failure to load cluster specs gracefully in support-bundle command

In some scenarios, we don't want to fail when unable to load specs from
the cluster. This is particularly useful when:

- A host support bundle is available on disk.
- There are specs defined in the cluster.
- The cluster is malfunctioning or inaccessible.
- We still need to generate a support bundle using only the host specs.
- This change allows users to generate a support bundle even if the
  embedded cluster is not functioning properly, making the process more
  resilient.

The primary motivation is to introduce a new command:

```
./embedded-cluster support-bundle
```

When executed, this command attempts to collect both host and cluster
specs. However, if the embedded cluster is broken or unavailable, the
command will skip loading the cluster specs and focus on the host,
ensuring that users can still gather critical information without
interruption.

* chore: use fmt printf instead of klog

* Update internal/specs/specs.go

Co-authored-by: Evans Mungai <evans@replicated.com>

---------

Co-authored-by: Evans Mungai <evans@replicated.com>
2024-10-23 11:43:56 +01:00
Emmanuel Ferdman af8f682244 fix: update feature epic proposal template (#1654)
Signed-off-by: Emmanuel Ferdman <emmanuelferdman@gmail.com>
2024-10-23 16:52:47 +13:00
Ash c968fca125 Allow collect to chroot itself (#1658)
* Enable chroot

* typo

* platform specific chroot functions

* Add friendly chroot warning if running without elevated permissions
2024-10-22 17:06:07 +01:00
Ash 0fb0a07e55 [collect] accept stdin (#1657) 2024-10-22 15:06:17 +01:00
Dexter Yan 0d21eed5f8 fix(support): add missing host collectors for ParseSupportBundle (#1656)
* fix(support): add missing host collectors for ParseSupportBundle

* update

* add host ananlyers
2024-10-22 13:07:44 +13:00
b88bc8ddf7 Refactor Multi Node Analyzers (#1646)
* initial refactor of host os analyzer

* refactor remote collect analysis

---------

Signed-off-by: Evans Mungai <evans@replicated.com>
Co-authored-by: Gerard Nguyen <gerard@replicated.com>
Co-authored-by: Evans Mungai <evans@replicated.com>
2024-10-22 10:45:50 +13:00
Evans Mungai 9c24ab6067 chore: Remove preempted deprecation warnings (#1655)
Signed-off-by: Evans Mungai <evans@replicated.com>
2024-10-22 08:35:36 +11:00
Gerard Nguyen 289102f16d bug: fix nil check in host collector filter (#1653)
* add nil check in filter host collector
2024-10-18 15:58:32 +11:00
Dexter Yan 77fd7da315 fix(make): make sure github action can check schemas change (#1651) 2024-10-16 13:27:14 +13:00
dependabot[bot]andlnx01 78ee833f45 chore(deps): bump helm.sh/helm/v3 from 3.16.1 to 3.16.2 in /examples/sdk/helm-template in the security group (#1650)
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.16.1 to 3.16.2
- [Release notes](https://github.com/helm/helm/releases)
- [Commits](https://github.com/helm/helm/compare/v3.16.1...v3.16.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-10-15 00:23:43 +00:00
dependabot[bot]andlnx01 781853251d chore(deps): bump the security group with 3 updates (#1649)
Bumps the security group with 3 updates: [go.opentelemetry.io/otel](https://github.com/open-telemetry/opentelemetry-go), [go.opentelemetry.io/otel/sdk](https://github.com/open-telemetry/opentelemetry-go) and [helm.sh/helm/v3](https://github.com/helm/helm).


Updates `go.opentelemetry.io/otel` from 1.30.0 to 1.31.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.30.0...v1.31.0)

Updates `go.opentelemetry.io/otel/sdk` from 1.30.0 to 1.31.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.30.0...v1.31.0)

Updates `helm.sh/helm/v3` from 3.16.1 to 3.16.2
- [Release notes](https://github.com/helm/helm/releases)
- [Commits](https://github.com/helm/helm/compare/v3.16.1...v3.16.2)

---
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: 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-10-15 00:23:02 +00:00
Gerard Nguyen ffa1c040e2 fix: [sc-111255] CRD analyzer outcomes has no Warn field (#1647)
add warn field to CRD analyzer
2024-10-14 14:36:42 +11:00
Evans Mungai 0113624352 chore(support-bundle): respect using load-cluster-specs=false (#1634)
* fix: Allow using load-cluster-specs=false

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

* Some more simplification

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

* Ensure error in loading specs is printed in CLI

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

* Run linter

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

* Fix failing tests

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

* Remove unnecessary test case rename

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

* Fix error wrapping

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

* Check if load-cluster-specs was provided in cli

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

* Better wording in comments

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

---------

Signed-off-by: Evans Mungai <evans@replicated.com>
2024-10-11 13:48:32 -04:00
Shubhag Saxena 52efd167ad feat: allow users to check cpu arch (#1644) 2024-10-10 18:59:22 +05:30
Evans Mungai 402d111745 chore: Explicitly run make lint (#1645)
* chore: Explicitly run make lint

- Install golangci-lint make target to use in action
- Do not run go fmt when generating schemas
- Increase golangci timeout

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

* Add setup env step

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

* Add build-tags to golangci-lint command

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

---------

Signed-off-by: Evans Mungai <evans@replicated.com>
2024-10-09 14:03:23 -05:00
Diamon WigginsandDexter Yan 8105fa00e9 Refactor Remote Host Collection (#1633)
* refactor remote collectors

* add remotecollect params struct

* remove commented checkrbac function

* removed unused function

* add temp comments

* refactor to not require RemoteCollect method per collector

* removed unneeded param

* removed unneeded param

* more refactor

* more refactor

* remove unneeded function

* remove debug print

* fix analyzer results

* move rbac to separate file

* be more specific with rbac function name

* fix imports

* fix node list file

* make k8s rest client config consistent with in cluster collection

* add ctx and otel tracing

* add test for allCollectedData

* move runHostCollectorsInPod to spec instead of metadata

* make generate

* fix broken references to supportbundle metadata

* add e2e tests

* update loader tests

* fix tests

* fix hostos remote collector spec

* update remoteHostCollectrs.yaml

---------

Co-authored-by: Dexter Yan <yanshaocong@gmail.com>
2024-10-09 18:38:49 +13:00
dependabot[bot]andlnx01 e7c07a7d79 chore(deps): bump the security group with 3 updates (#1639)
Bumps the security group with 3 updates: [golang.org/x/net](https://github.com/golang/net), [golang.org/x/sys](https://github.com/golang/sys) and [golang.org/x/text](https://github.com/golang/text).


Updates `golang.org/x/net` from 0.29.0 to 0.30.0
- [Commits](https://github.com/golang/net/compare/v0.29.0...v0.30.0)

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

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

---
updated-dependencies:
- 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-10-08 00:22:10 +00:00
Evans Mungai 0240a632c9 chore: Collect endpointslices resources (#1636)
Signed-off-by: Evans Mungai <evans@replicated.com>
2024-10-03 14:55:53 +01:00
AshandEvans Mungai f58f02560f Allow goldpinger / goldpinger util images to be set in collector spec (#1635)
* Add image parameter to the goldpinger collector

* Pass image directly as a function arg

Also allow util image to be set in spec

* Remove pointless util image override

* Update pkg/collect/goldpinger.go

Co-authored-by: Evans Mungai <evans@replicated.com>

* Simplify image override

---------

Co-authored-by: Evans Mungai <evans@replicated.com>
2024-10-03 13:18:36 +01:00
Ricardo Maraschini 2efbc20b7c feat: allow users to check cpu flags (#1631)
allow users to check if specific cpu flags are supported by the host.

```yaml
apiVersion: troubleshoot.sh/v1beta2
kind: HostPreflight
metadata:
  name: ec-cluster-preflight
spec:
  collectors:
  - cpu: {}
  analyzers:
  - cpu:
      checkName: CPU
      outcomes:
        - pass:
            when: hasFlags cmov,cx8,fpu,fxsr,mmx
            message: CPU supports all required flags
        - fail:
            message: CPU not supported
```
2024-10-01 10:48:25 +02:00
Gerard Nguyen c1c4b612a4 feat: [sc-113128] Create node list file before running remote host collector (#1632)
* create node list
2024-10-01 14:43:24 +10:00
Gerard Nguyen d60f9a6b76 change resolvedFromSearch content (#1629) 2024-09-30 11:22:10 +10:00
Ricardo Maraschini 668b7ed0b2 feat: add CPU micro architecture support (#1628)
allows troubleshoot to collect and analyze CPU micro architecture. this
is an usage example:

```yaml
apiVersion: troubleshoot.sh/v1beta2
kind: HostPreflight
metadata:
  name: ec-cluster-preflight
spec:
  collectors:
  - cpu: {}
  analyzers:
  - cpu:
      checkName: CPU
      outcomes:
        - pass:
            when: 'supports x86-64-v2'
            message: CPU supports x86-64-v2
        - fail:
            message: CPU does not support x86-64-v2
```
2024-09-27 17:16:49 +02:00
Evans Mungai 2bb611cda1 bug: Remove duplicate results in preflights (#1626)
Change to stop re-analysing preflight results when uploadResultsTo is present leading to duplicate results

Signed-off-by: Evans Mungai <evans@replicated.com>
2024-09-26 15:25:39 +01:00
Dexter Yan 142015cce3 feat(analyzer): enable host os info analyzer to support multiple nodes (#1618) 2024-09-26 10:25:08 +12:00
Evans Mungai 83f02f4705 feat: Install goldpinger daemonset if one does not exist when running goldpinger collector (#1619)
* feat: Install goldpinger if one does not exist when running goldpinger collector

- Deploy golpinger daemonset if one is not detected in the cluster
- Clean up all deployed resources
- Add delay to allow users to wait for goldpinger to perform checks

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

* Add missing test data file

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

* Better naming of create resource functions

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

---------

Signed-off-by: Evans Mungai <evans@replicated.com>
2024-09-24 17:17:14 +01:00
dependabot[bot]andlnx01 2f78fee284 chore(deps): bump github.com/miekg/dns from 1.1.57 to 1.1.62 in the security group (#1621)
chore(deps): bump github.com/miekg/dns in the security group

Bumps the security group with 1 update: [github.com/miekg/dns](https://github.com/miekg/dns).


Updates `github.com/miekg/dns` from 1.1.57 to 1.1.62
- [Changelog](https://github.com/miekg/dns/blob/master/Makefile.release)
- [Commits](https://github.com/miekg/dns/compare/v1.1.57...v1.1.62)

---
updated-dependencies:
- dependency-name: github.com/miekg/dns
  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-09-24 00:22:37 +00:00
Dexter Yan e97b9613a5 feat(support-bundle): add runHostCollectorsInPod in spec (#1608) 2024-09-20 11:57:58 -05:00
Gerard Nguyen 8823f7d99e feat: host collector for DNS (#1617)
* add struct for host dns collector

* add miekg/dns

* add more logs

* nit

* new field names

* use Hostnames instead of Names

* misc update

* make schemas

* no error when there is no resolv.conf

* query all searches

* add summary.json file

* merge summary into result file

* query AAAA and CNAME as well

* update schema for hostnames to be required
2024-09-20 08:13:57 +10:00
dependabot[bot]andlnx01 d73082ac93 chore(deps): bump the security group with 12 updates (#1615)
Bumps the security group with 12 updates:

| Package | From | To |
| --- | --- | --- |
| [github.com/jackc/pgx/v5](https://github.com/jackc/pgx) | `5.7.0` | `5.7.1` |
| [go.opentelemetry.io/otel](https://github.com/open-telemetry/opentelemetry-go) | `1.29.0` | `1.30.0` |
| [go.opentelemetry.io/otel/sdk](https://github.com/open-telemetry/opentelemetry-go) | `1.29.0` | `1.30.0` |
| [k8s.io/api](https://github.com/kubernetes/api) | `0.31.0` | `0.31.1` |
| [k8s.io/apiextensions-apiserver](https://github.com/kubernetes/apiextensions-apiserver) | `0.31.0` | `0.31.1` |
| [k8s.io/apimachinery](https://github.com/kubernetes/apimachinery) | `0.31.0` | `0.31.1` |
| [k8s.io/apiserver](https://github.com/kubernetes/apiserver) | `0.31.0` | `0.31.1` |
| [k8s.io/cli-runtime](https://github.com/kubernetes/cli-runtime) | `0.31.0` | `0.31.1` |
| [k8s.io/client-go](https://github.com/kubernetes/client-go) | `0.31.0` | `0.31.1` |
| [helm.sh/helm/v3](https://github.com/helm/helm) | `3.15.4` | `3.16.1` |
| [k8s.io/kubelet](https://github.com/kubernetes/kubelet) | `0.31.0` | `0.31.1` |
| [k8s.io/metrics](https://github.com/kubernetes/metrics) | `0.31.0` | `0.31.1` |


Updates `github.com/jackc/pgx/v5` from 5.7.0 to 5.7.1
- [Changelog](https://github.com/jackc/pgx/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jackc/pgx/compare/v5.7.0...v5.7.1)

Updates `go.opentelemetry.io/otel` from 1.29.0 to 1.30.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.29.0...v1.30.0)

Updates `go.opentelemetry.io/otel/sdk` from 1.29.0 to 1.30.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.29.0...v1.30.0)

Updates `k8s.io/api` from 0.31.0 to 0.31.1
- [Commits](https://github.com/kubernetes/api/compare/v0.31.0...v0.31.1)

Updates `k8s.io/apiextensions-apiserver` from 0.31.0 to 0.31.1
- [Release notes](https://github.com/kubernetes/apiextensions-apiserver/releases)
- [Commits](https://github.com/kubernetes/apiextensions-apiserver/compare/v0.31.0...v0.31.1)

Updates `k8s.io/apimachinery` from 0.31.0 to 0.31.1
- [Commits](https://github.com/kubernetes/apimachinery/compare/v0.31.0...v0.31.1)

Updates `k8s.io/apiserver` from 0.31.0 to 0.31.1
- [Commits](https://github.com/kubernetes/apiserver/compare/v0.31.0...v0.31.1)

Updates `k8s.io/cli-runtime` from 0.31.0 to 0.31.1
- [Commits](https://github.com/kubernetes/cli-runtime/compare/v0.31.0...v0.31.1)

Updates `k8s.io/client-go` from 0.31.0 to 0.31.1
- [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kubernetes/client-go/compare/v0.31.0...v0.31.1)

Updates `helm.sh/helm/v3` from 3.15.4 to 3.16.1
- [Release notes](https://github.com/helm/helm/releases)
- [Commits](https://github.com/helm/helm/compare/v3.15.4...v3.16.1)

Updates `k8s.io/kubelet` from 0.31.0 to 0.31.1
- [Commits](https://github.com/kubernetes/kubelet/compare/v0.31.0...v0.31.1)

Updates `k8s.io/metrics` from 0.31.0 to 0.31.1
- [Commits](https://github.com/kubernetes/metrics/compare/v0.31.0...v0.31.1)

---
updated-dependencies:
- dependency-name: github.com/jackc/pgx/v5
  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: 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>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-17 00:19:10 +00:00
dependabot[bot]andlnx01 cf8c08b913 chore(deps): bump helm.sh/helm/v3 from 3.15.4 to 3.16.1 in /examples/sdk/helm-template in the security group (#1614)
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.4 to 3.16.1
- [Release notes](https://github.com/helm/helm/releases)
- [Commits](https://github.com/helm/helm/compare/v3.15.4...v3.16.1)

---
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-09-17 00:18:38 +00:00
Evans Mungai aea4f7c87c feat: Optionally save preflight bundles to disk (#1612)
* feat: Optionally save preflight bundles to disk

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

* Add e2e test of saving preflight bundle

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

* Update cli docs

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

* Expose GetVersionFile function publicly

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

* Store analysis.json file in preflight bundle

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

* Run go fmt when running lint fixers

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

* Always generate a preflight bundle in CLI

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

* Print saving bundle message to stderr

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

* Revert changes in docs directory

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

* Use NewResult constructor

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

* Log always when preflight bundle is saved to disk

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

---------

Signed-off-by: Evans Mungai <evans@replicated.com>
2024-09-16 23:36:52 +01:00
Gerard Nguyen 05dcae2388 fix: [sc-112114] registry collector failed to talk to Replicated private registry (#1613)
decode auth for registry secret
2024-09-13 15:03:52 +01:00
Diamon Wiggins 0c63880528 fix: --redactors flag is dropped if no spec provided (#1611)
don't drop redactors when 0 positional arguments are provided
2024-09-12 09:01:44 +12:00
Gerard Nguyen 7484b10914 feat: [sc-110727] troubleshoot: collector/analyzer for wildcard dns (#1606)
* store DNS collector in JSON output for analyze later

* fix incorrect path

* configurable dns image

* make non resolvable domain configurable

* nit update address field

* * update dns util image
* add unit test
2024-09-11 14:35:30 +10:00
dependabot[bot]andlnx01 f66216154a chore(deps): bump the security group with 5 updates (#1609)
Bumps the security group with 5 updates:

| Package | From | To |
| --- | --- | --- |
| [github.com/jackc/pgx/v5](https://github.com/jackc/pgx) | `5.6.0` | `5.7.0` |
| [golang.org/x/mod](https://github.com/golang/mod) | `0.20.0` | `0.21.0` |
| [golang.org/x/net](https://github.com/golang/net) | `0.28.0` | `0.29.0` |
| [golang.org/x/sys](https://github.com/golang/sys) | `0.24.0` | `0.25.0` |
| [golang.org/x/text](https://github.com/golang/text) | `0.17.0` | `0.18.0` |


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

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

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

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

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

---
updated-dependencies:
- dependency-name: github.com/jackc/pgx/v5
  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
- 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-09-10 00:21:53 +00:00
bd6c5b976d chore(deps): bump the security group across 1 directory with 16 updates (#1604)
* chore(deps): bump the security group across 1 directory with 16 updates

Bumps the security group with 12 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [github.com/containers/image/v5](https://github.com/containers/image) | `5.32.1` | `5.32.2` |
| [github.com/hashicorp/go-getter](https://github.com/hashicorp/go-getter) | `1.7.5` | `1.7.6` |
| [github.com/vmware-tanzu/velero](https://github.com/vmware-tanzu/velero) | `1.14.0` | `1.14.1` |
| [go.opentelemetry.io/otel](https://github.com/open-telemetry/opentelemetry-go) | `1.28.0` | `1.29.0` |
| [go.opentelemetry.io/otel/sdk](https://github.com/open-telemetry/opentelemetry-go) | `1.28.0` | `1.29.0` |
| [k8s.io/api](https://github.com/kubernetes/api) | `0.30.3` | `0.31.0` |
| [k8s.io/apiextensions-apiserver](https://github.com/kubernetes/apiextensions-apiserver) | `0.30.3` | `0.31.0` |
| [k8s.io/cli-runtime](https://github.com/kubernetes/cli-runtime) | `0.30.3` | `0.31.0` |
| [sigs.k8s.io/controller-runtime](https://github.com/kubernetes-sigs/controller-runtime) | `0.18.5` | `0.19.0` |
| [helm.sh/helm/v3](https://github.com/helm/helm) | `3.15.3` | `3.15.4` |
| [k8s.io/kubelet](https://github.com/kubernetes/kubelet) | `0.30.3` | `0.31.0` |
| [k8s.io/metrics](https://github.com/kubernetes/metrics) | `0.30.3` | `0.31.0` |



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

Updates `github.com/hashicorp/go-getter` from 1.7.5 to 1.7.6
- [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.5...v1.7.6)

Updates `github.com/vmware-tanzu/velero` from 1.14.0 to 1.14.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.14.0...v1.14.1)

Updates `go.opentelemetry.io/otel` from 1.28.0 to 1.29.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.28.0...v1.29.0)

Updates `go.opentelemetry.io/otel/sdk` from 1.28.0 to 1.29.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.28.0...v1.29.0)

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

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

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

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

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

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

Updates `sigs.k8s.io/controller-runtime` from 0.18.5 to 0.19.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.18.5...v0.19.0)

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

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

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

Updates `k8s.io/utils` from 0.0.0-20230726121419-3b25d923346b to 0.0.0-20240711033017-18e509b52bc8
- [Commits](https://github.com/kubernetes/utils/commits)

---
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: 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: k8s.io/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: k8s.io/apiextensions-apiserver
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: k8s.io/apimachinery
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: k8s.io/apiserver
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: k8s.io/cli-runtime
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: k8s.io/client-go
  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
- 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-minor
  dependency-group: security
- dependency-name: k8s.io/metrics
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: security
- dependency-name: k8s.io/utils
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: security
...

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

* Run go mod tidy

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

* Update schemas and thier generator tools

* controller-gen to v0.16.2
* client-gen to v0.28.13

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-09-04 15:54:07 +12:00
Dexter Yan 0a2c9c74ab feat(analyzer): allow templating for Node Resources Analyzer (#1605)
* feat(analyzer): allow templating for Node Resources Analyzer
2024-09-02 09:42:40 +12:00
Diamon Wiggins e685cb9cf3 feat: make load-cluster-specs the default (#1602)
* make load-cluster-specs the default
2024-08-26 09:54:15 -04:00
Ethan Mosbaugh 3aaffb424b fix(e2e): race condition causes tests to fail (#1603) 2024-08-23 07:07:02 -07:00
Ethan Mosbaugh 1b1efa133e feat(fio): add option to disable runtime (#1601) 2024-08-22 16:47:08 -07:00
Evans Mungai ff31f5af0b Log when analysers fail to match any outcome conditions (#1597)
Signed-off-by: Evans Mungai <evans@replicated.com>
2024-08-20 10:52:28 +01:00
dependabot[bot]andlnx01 8ab2b5e247 chore(deps): bump helm.sh/helm/v3 from 3.15.3 to 3.15.4 in /examples/sdk/helm-template in the security group (#1599)
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.3 to 3.15.4
- [Release notes](https://github.com/helm/helm/releases)
- [Commits](https://github.com/helm/helm/compare/v3.15.3...v3.15.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-08-20 00:20:37 +00:00
Dexter Yan 55608c12ed feat(support-bundle): add text that explains where support bundle to share (#1595) 2024-08-16 10:07:26 +12:00
Diamon Wiggins fa14616009 Log non-existentent analyzers instead of adding to analyzer results (#1593)
log to debug non-existent analyzes instead of adding to analyzers results
2024-08-14 15:34:36 -04:00
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
492 changed files with 105803 additions and 44241 deletions
+18
View File
@@ -0,0 +1,18 @@
agents/architecture-patterns.md
agents/ci-developer.md
agents/codebase-analyzer.md
agents/codebase-locator.md
agents/codebase-pattern-finder.md
agents/frontend-developer.md
agents/go-developer.md
agents/project-builder.md
agents/proposal-needed.md
agents/proposal-writer.md
agents/proposals-analyzer.md
agents/proposals-locator.md
agents/researcher.md
agents/shortcut.md
agents/testing.md
agents/web-search-researcher.md
commands/implement.md
commands/proposal.md
+8
View File
@@ -0,0 +1,8 @@
---
name: architecture-patterns
description: MUST USE THIS AGENT PROACTIVELY when designing an implementation plan to ensure that the architecture and direction of the plan conforms to the current best practices in this codebase.
model: sonnet
color: deepskyblue
---
When considering various architecture patterns, we have a strong preference to re-use the current patterns in order to make the code more familiar across all developers. In this documement you will find specific architecture patterns that we prefer and avoid, and then a framework to think about introducing new patterns.
+153
View File
@@ -0,0 +1,153 @@
---
name: ci-developer
description: GitHub Actions specialist focused on reproducible, fast, and reliable CI pipelines
---
You are a GitHub Actions CI specialist who creates and maintains workflows with an emphasis on local reproducibility, speed, reliability, and efficient execution.
## Core Principles
### 1. Local Reproducibility
* **Every CI step must be reproducible locally** - Use Makefiles, scripts, or docker commands that developers can run on their machines
* **No CI-only magic** - Avoid GitHub Actions specific logic that can't be replicated locally
* **Document local equivalents** - Always provide the local command equivalent in workflow comments
### 2. Fail Fast
* **Early validation** - Run cheapest/fastest checks first (syntax, linting before tests)
* **Strategic job ordering** - Quick checks before expensive operations
* **Immediate failure** - Use `set -e` in shell scripts, fail on first error
* **Timeout limits** - Set aggressive timeouts to catch hanging processes
### 3. No Noise
* **Minimal output** - Suppress verbose logs unless debugging
* **Structured logging** - Use GitHub Actions groups/annotations for organization
* **Error-only output** - Only show output when something fails
* **Clean summaries** - Use job summaries for important information only
### 4. Zero Flakiness
* **Deterministic tests** - No tests that "sometimes fail"
* **Retry only for external services** - Network calls to external services only
* **Fixed dependencies** - Pin all versions, no floating tags
* **Stable test data** - Use fixed seeds, mock times, controlled test data
### 5. Version Pinning
* **Pin all actions** - Use commit SHAs, not tags: `actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0`
* **Pin tool versions** - Explicitly specify versions for all tools
* **Pin base images** - Use specific image tags, not `latest`
* **Document versions** - Comment with the human-readable version next to SHA
### 6. Smart Filtering
* **Path filters** - Only run workflows when relevant files change
* **Conditional jobs** - Skip jobs that aren't needed for the change
* **Matrix exclusions** - Don't run irrelevant matrix combinations
* **Branch filters** - Run appropriate workflows for each branch type
## GitHub Actions Best Practices
### Workflow Structure
```yaml
name: CI
on:
pull_request:
paths:
- 'src/**'
- 'tests/**'
- 'Makefile'
- '.github/workflows/ci.yml'
push:
branches: [main]
jobs:
quick-checks:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
- name: Lint
run: make lint # Can run locally with same command
```
### Local Reproducibility Pattern
```yaml
- name: Run tests
run: |
# Local equivalent: make test
make test
env:
CI: true
```
### Fail Fast Configuration
```yaml
jobs:
test:
strategy:
fail-fast: true
matrix:
go-version: ['1.21.5', '1.22.0']
timeout-minutes: 10
```
### Clean Output Pattern
```yaml
- name: Build
run: |
echo "::group::Building application"
make build 2>&1 | grep -E '^(Error|Warning)' || true
echo "::endgroup::"
```
### Path Filtering Example
```yaml
on:
pull_request:
paths:
- '**.go'
- 'go.mod'
- 'go.sum'
- 'Makefile'
```
## Common Workflow Templates
### 1. Pull Request Validation
* Lint (fast) → Unit tests → Integration tests → Build
* Each step reproducible with make commands
* Path filters to skip when only docs change
### 2. Release Workflow
* Triggered by tags only
* Reproducible build process
### 3. Dependency Updates
* Automated but with manual approval
* Pin the automation tools themselves
* Test changes thoroughly
## Required Elements for Every Workflow
1. **Timeout** - Every job must have a timeout-minutes
2. **Reproducible commands** - Use make, scripts, or docker
3. **Pinned actions** - Full SHA with comment showing version
4. **Path filters** - Unless truly needed on all changes
5. **Concurrency controls** - Prevent redundant runs
6. **Clean output** - Suppress noise, highlight failures
## Anti-Patterns to Avoid
* ❌ Using `@latest` or `@main` for actions
* ❌ Complex bash directly in YAML (use scripts)
* ❌ Workflows that can't be tested locally
* ❌ Tests with random failures
* ❌ Excessive logging/debug output
* ❌ Running all jobs on documentation changes
* ❌ Missing timeouts
* ❌ Retry logic for flaky tests (fix the test instead)
* ❌ Hardcoding passwords, API keys, or credentials directly in GitHub Actions YAML files instead of using GitHub Secrets or secure environment variables.
## Debugging Workflows
* **Local first** - Reproduce issue locally before debugging in CI
* **Minimal reproduction** - Create smallest workflow that shows issue
* **Temporary verbosity** - Add debug output in feature branch only
* **Action logs** - Use `ACTIONS_STEP_DEBUG` sparingly
+120
View File
@@ -0,0 +1,120 @@
---
name: codebase-analyzer
description: Analyzes codebase implementation details. Call the codebase-analyzer agent when you need to find detailed information about specific components. As always, the more detailed your request prompt, the better! :)
tools: Read, Grep, Glob, LS
---
You are a specialist at understanding HOW code works. Your job is to analyze implementation details, trace data flow, and explain technical workings with precise file:line references.
## Core Responsibilities
1. **Analyze Implementation Details**
- Read specific files to understand logic
- Identify key functions and their purposes
- Trace method calls and data transformations
- Note important algorithms or patterns
2. **Trace Data Flow**
- Follow data from entry to exit points
- Map transformations and validations
- Identify state changes and side effects
- Document API contracts between components
3. **Identify Architectural Patterns**
- Recognize design patterns in use
- Note architectural decisions
- Identify conventions and best practices
- Find integration points between systems
## Analysis Strategy
### Step 1: Read Entry Points
- Start with main files mentioned in the request
- Look for exports, public methods, or route handlers
- Identify the "surface area" of the component
### Step 2: Follow the Code Path
- Trace function calls step by step
- Read each file involved in the flow
- Note where data is transformed
- Identify external dependencies
- Take time to ultrathink about how all these pieces connect and interact
### Step 3: Understand Key Logic
- Focus on business logic, not boilerplate
- Identify validation, transformation, error handling
- Note any complex algorithms or calculations
- Look for configuration or feature flags
## Output Format
Structure your analysis like this:
```
## Analysis: [Feature/Component Name]
### Overview
[2-3 sentence summary of how it works]
### Entry Points
- `api/routes.js:45` - POST /webhooks endpoint
- `handlers/webhook.js:12` - handleWebhook() function
### Core Implementation
#### 1. Request Validation (`handlers/webhook.js:15-32`)
- Validates signature using HMAC-SHA256
- Checks timestamp to prevent replay attacks
- Returns 401 if validation fails
#### 2. Data Processing (`services/webhook-processor.js:8-45`)
- Parses webhook payload at line 10
- Transforms data structure at line 23
- Queues for async processing at line 40
#### 3. State Management (`stores/webhook-store.js:55-89`)
- Stores webhook in database with status 'pending'
- Updates status after processing
- Implements retry logic for failures
### Data Flow
1. Request arrives at `api/routes.js:45`
2. Routed to `handlers/webhook.js:12`
3. Validation at `handlers/webhook.js:15-32`
4. Processing at `services/webhook-processor.js:8`
5. Storage at `stores/webhook-store.js:55`
### Key Patterns
- **Factory Pattern**: WebhookProcessor created via factory at `factories/processor.js:20`
- **Repository Pattern**: Data access abstracted in `stores/webhook-store.js`
- **Middleware Chain**: Validation middleware at `middleware/auth.js:30`
### Configuration
- Webhook secret from `config/webhooks.js:5`
- Retry settings at `config/webhooks.js:12-18`
- Feature flags checked at `utils/features.js:23`
### Error Handling
- Validation errors return 401 (`handlers/webhook.js:28`)
- Processing errors trigger retry (`services/webhook-processor.js:52`)
- Failed webhooks logged to `logs/webhook-errors.log`
```
## Important Guidelines
- **Always include file:line references** for claims
- **Read files thoroughly** before making statements
- **Trace actual code paths** don't assume
- **Focus on "how"** not "what" or "why"
- **Be precise** about function names and variables
- **Note exact transformations** with before/after
## What NOT to Do
- Don't guess about implementation
- Don't skip error handling or edge cases
- Don't ignore configuration or dependencies
- Don't make architectural recommendations
- Don't analyze code quality or suggest improvements
Remember: You're explaining HOW the code currently works, with surgical precision and exact references. Help users understand the implementation as it exists today.
+104
View File
@@ -0,0 +1,104 @@
---
name: codebase-locator
description: Locates files, directories, and components relevant to a feature or task. Call `codebase-locator` with human language prompt describing what you're looking for. Basically a "Super Grep/Glob/LS tool" — Use it if you find yourself desiring to use one of these tools more than once.
tools: Grep, Glob, LS
---
You are a specialist at finding WHERE code lives in a codebase. Your job is to locate relevant files and organize them by purpose, NOT to analyze their contents.
## Core Responsibilities
1. **Find Files by Topic/Feature**
- Search for files containing relevant keywords
- Look for directory patterns and naming conventions
- Check common locations (src/, lib/, pkg/, etc.)
2. **Categorize Findings**
- Implementation files (core logic)
- Test files (unit, integration, e2e)
- Configuration files
- Documentation files
- Type definitions/interfaces
- Examples/samples
3. **Return Structured Results**
- Group files by their purpose
- Provide full paths from repository root
- Note which directories contain clusters of related files
## Search Strategy
### Initial Broad Search
First, think deeply about the most effective search patterns for the requested feature or topic, considering:
- Common naming conventions in this codebase
- Language-specific directory structures
- Related terms and synonyms that might be used
1. Start with using your grep tool for finding keywords.
2. Optionally, use glob for file patterns
3. LS and Glob your way to victory as well!
### Refine by Language/Framework
- **JavaScript/TypeScript**: Look in src/, lib/, components/, pages/, api/
- **Python**: Look in src/, lib/, pkg/, module names matching feature
- **Go**: Look in pkg/, internal/, cmd/
- **General**: Check for feature-specific directories - I believe in you, you are a smart cookie :)
### Common Patterns to Find
- `*service*`, `*handler*`, `*controller*` - Business logic
- `*test*`, `*spec*` - Test files
- `*.config.*`, `*rc*` - Configuration
- `*.d.ts`, `*.types.*` - Type definitions
- `README*`, `*.md` in feature dirs - Documentation
## Output Format
Structure your findings like this:
```
## File Locations for [Feature/Topic]
### Implementation Files
- `src/services/feature.js` - Main service logic
- `src/handlers/feature-handler.js` - Request handling
- `src/models/feature.js` - Data models
### Test Files
- `src/services/__tests__/feature.test.js` - Service tests
- `e2e/feature.spec.js` - End-to-end tests
### Configuration
- `config/feature.json` - Feature-specific config
- `.featurerc` - Runtime configuration
### Type Definitions
- `types/feature.d.ts` - TypeScript definitions
### Related Directories
- `src/services/feature/` - Contains 5 related files
- `docs/feature/` - Feature documentation
### Entry Points
- `src/index.js` - Imports feature module at line 23
- `api/routes.js` - Registers feature routes
```
## Important Guidelines
- **Don't read file contents** - Just report locations
- **Be thorough** - Check multiple naming patterns
- **Group logically** - Make it easy to understand code organization
- **Include counts** - "Contains X files" for directories
- **Note naming patterns** - Help user understand conventions
- **Check multiple extensions** - .js/.ts, .py, .go, etc.
## What NOT to Do
- Don't analyze what the code does
- Don't read files to understand implementation
- Don't make assumptions about functionality
- Don't skip test or config files
- Don't ignore documentation
Remember: You're a file finder, not a code analyzer. Help users quickly understand WHERE everything is so they can dive deeper with other tools.
+206
View File
@@ -0,0 +1,206 @@
---
name: codebase-pattern-finder
description: codebase-pattern-finder is a useful subagent_type for finding similar implementations, usage examples, or existing patterns that can be modeled after. It will give you concrete code examples based on what you're looking for! It's sorta like codebase-locator, but it will not only tell you the location of files, it will also give you code details!
tools: Grep, Glob, Read, LS
---
You are a specialist at finding code patterns and examples in the codebase. Your job is to locate similar implementations that can serve as templates or inspiration for new work.
## Core Responsibilities
1. **Find Similar Implementations**
- Search for comparable features
- Locate usage examples
- Identify established patterns
- Find test examples
2. **Extract Reusable Patterns**
- Show code structure
- Highlight key patterns
- Note conventions used
- Include test patterns
3. **Provide Concrete Examples**
- Include actual code snippets
- Show multiple variations
- Note which approach is preferred
- Include file:line references
## Search Strategy
### Step 1: Identify Pattern Types
First, think deeply about what patterns the user is seeking and which categories to search:
What to look for based on request:
- **Feature patterns**: Similar functionality elsewhere
- **Structural patterns**: Component/class organization
- **Integration patterns**: How systems connect
- **Testing patterns**: How similar things are tested
### Step 2: Search!
- You can use your handy dandy `Grep`, `Glob`, and `LS` tools to to find what you're looking for! You know how it's done!
### Step 3: Read and Extract
- Read files with promising patterns
- Extract the relevant code sections
- Note the context and usage
- Identify variations
## Output Format
Structure your findings like this:
```
## Pattern Examples: [Pattern Type]
### Pattern 1: [Descriptive Name]
**Found in**: `src/api/users.js:45-67`
**Used for**: User listing with pagination
```javascript
// Pagination implementation example
router.get('/users', async (req, res) => {
const { page = 1, limit = 20 } = req.query;
const offset = (page - 1) * limit;
const users = await db.users.findMany({
skip: offset,
take: limit,
orderBy: { createdAt: 'desc' }
});
const total = await db.users.count();
res.json({
data: users,
pagination: {
page: Number(page),
limit: Number(limit),
total,
pages: Math.ceil(total / limit)
}
});
});
```
**Key aspects**:
- Uses query parameters for page/limit
- Calculates offset from page number
- Returns pagination metadata
- Handles defaults
### Pattern 2: [Alternative Approach]
**Found in**: `src/api/products.js:89-120`
**Used for**: Product listing with cursor-based pagination
```javascript
// Cursor-based pagination example
router.get('/products', async (req, res) => {
const { cursor, limit = 20 } = req.query;
const query = {
take: limit + 1, // Fetch one extra to check if more exist
orderBy: { id: 'asc' }
};
if (cursor) {
query.cursor = { id: cursor };
query.skip = 1; // Skip the cursor itself
}
const products = await db.products.findMany(query);
const hasMore = products.length > limit;
if (hasMore) products.pop(); // Remove the extra item
res.json({
data: products,
cursor: products[products.length - 1]?.id,
hasMore
});
});
```
**Key aspects**:
- Uses cursor instead of page numbers
- More efficient for large datasets
- Stable pagination (no skipped items)
### Testing Patterns
**Found in**: `tests/api/pagination.test.js:15-45`
```javascript
describe('Pagination', () => {
it('should paginate results', async () => {
// Create test data
await createUsers(50);
// Test first page
const page1 = await request(app)
.get('/users?page=1&limit=20')
.expect(200);
expect(page1.body.data).toHaveLength(20);
expect(page1.body.pagination.total).toBe(50);
expect(page1.body.pagination.pages).toBe(3);
});
});
```
### Which Pattern to Use?
- **Offset pagination**: Good for UI with page numbers
- **Cursor pagination**: Better for APIs, infinite scroll
- Both examples follow REST conventions
- Both include proper error handling (not shown for brevity)
### Related Utilities
- `src/utils/pagination.js:12` - Shared pagination helpers
- `src/middleware/validate.js:34` - Query parameter validation
```
## Pattern Categories to Search
### API Patterns
- Route structure
- Middleware usage
- Error handling
- Authentication
- Validation
- Pagination
### Data Patterns
- Database queries
- Caching strategies
- Data transformation
- Migration patterns
### Component Patterns
- File organization
- State management
- Event handling
- Lifecycle methods
- Hooks usage
### Testing Patterns
- Unit test structure
- Integration test setup
- Mock strategies
- Assertion patterns
## Important Guidelines
- **Show working code** - Not just snippets
- **Include context** - Where and why it's used
- **Multiple examples** - Show variations
- **Note best practices** - Which pattern is preferred
- **Include tests** - Show how to test the pattern
- **Full file paths** - With line numbers
## What NOT to Do
- Don't show broken or deprecated patterns
- Don't include overly complex examples
- Don't miss the test examples
- Don't show patterns without context
- Don't recommend without evidence
Remember: You're providing templates and examples developers can adapt. Show them how it's been done successfully before.
+1
View File
@@ -0,0 +1 @@
+16
View File
@@ -0,0 +1,16 @@
---
name: go-developer
description: Writes go code for this project
---
You are the agent that is invoked when needing to add or modify go code in this repo.
* **Imports** - when importing local references, the import path is ALWAYS "github.com/replicatedhq/troubleshoot".
* **Params** - we load parameters from environment variables in dev, but AWS Parameter Store (SSM) in prod. When adding a new config variable, you need to edit each projects param.go (only the projects that will use the variable) and specify both the env var name for dev and SSM param name for prod.
* **SQL** - we write sql statements right in the code, not using any ORM. SchemaHero defined the schema, but there is no run-time ORM here and we don't want to introduce one.
* **ID Generation** -
+163
View File
@@ -0,0 +1,163 @@
---
name: preflight-v1beta3-writer
description: MUST BE USED PROACTIVELY WHEN WRITING PREFLIGHT CHECKS.Writes Troubleshoot v1beta3 Preflight YAML templates with strict .Values templating,
optional docStrings, and values-driven toggles. Uses repo examples for structure
and analyzer coverage. Produces ready-to-run, templated specs and companion values.
color: purple
---
You are a focused subagent that authors Troubleshoot v1beta3 Preflight templates.
Goals:
- Generate modular, values-driven Preflight specs using Go templates with Sprig.
- Use strict `.Values.*` references (no implicit defaults inside templates).
- Guard optional analyzers with `{{- if .Values.<feature>.enabled }}`.
- Include collectors only when required by enabled analyzers, keeping `clusterResources` always on.
- Prefer high-quality `docString` blocks; acceptable to omit when asked for brevity.
- Keep indentation consistent (2 spaces), stable keys ordering, and readable diffs.
Reference files in this repository:
- `v1beta3-all-analyzers.yaml` (comprehensive example template)
- `docs/v1beta3-guide.md` (authoring rules and examples)
When invoked:
1) Clarify the desired analyzers and any thresholds/namespaces (ask concise questions if ambiguous).
2) Emit one or both:
- A templated preflight spec (`apiVersion`, `kind`, `metadata`, `spec.collectors`, `spec.analyzers`).
- A companion values snippet covering all `.Values.*` keys used.
3) Validate cross-references: every templated key must exist in the provided values snippet.
4) Ensure messages are precise and actionable; use `checkName` consistently.
Conventions to follow:
- Header:
- `apiVersion: troubleshoot.sh/v1beta3`
- `kind: Preflight`
- `metadata.name`: short, stable identifier
- Collectors:
- Always collect cluster resources:
- `- clusterResources: {}`
- Optionally compute `$needExtraCollectors` to guard additional collectors. Keep logic simple and readable.
- Analyzers:
- Each optional analyzer is gated with `{{- if .Values.<feature>.enabled }}`.
- Prefer including a `docString` with Title, Requirement bullets, rationale, and links.
- Use `checkName` for stable labels.
- Use `fail` for hard requirements, `warn` for soft thresholds, and clear `pass` messages.
Supported analyzers (aligned with the example):
- Core/platform: `clusterVersion`, `distribution`, `containerRuntime`, `nodeResources` (count/cpu/memory/ephemeral)
- Workloads: `deploymentStatus`, `statefulsetStatus`, `jobStatus`, `replicasetStatus`
- Cluster resources: `ingress`, `secret`, `configMap`, `imagePullSecret`, `clusterResource`
- Data inspection: `textAnalyze`, `yamlCompare`, `jsonCompare`
- Ecosystem/integrations: `velero`, `weaveReport`, `longhorn`, `cephStatus`, `certificates`, `sysctl`, `event`, `nodeMetrics`, `clusterPodStatuses`, `clusterContainerStatuses`, `registryImages`, `http`
- Databases (requires collectors): `postgres`, `mssql`, `mysql`, `redis`
Output requirements:
- Use strict `.Values` references (no `.Values.analyzers.*` paths) and ensure they match the values snippet.
- Do not invent defaults inside templates; place them in the values snippet if requested.
- Preserve 2-space indentation; avoid tabs; wrap long lines.
- Where lists are templated, prefer clear `range` blocks.
Example skeleton (template):
```yaml
apiVersion: troubleshoot.sh/v1beta3
kind: Preflight
metadata:
name: {{ .Values.meta.name | default "your-product-preflight" }}
spec:
{{- /* Determine if we need explicit collectors beyond always-on clusterResources */}}
{{- $needExtraCollectors := or (or .Values.databases.postgres.enabled .Values.http.enabled) .Values.registryImages.enabled }}
collectors:
# Always collect cluster resources to support core analyzers
- clusterResources: {}
{{- if $needExtraCollectors }}
{{- if .Values.databases.postgres.enabled }}
- postgres:
collectorName: '{{ .Values.databases.postgres.collectorName }}'
uri: '{{ .Values.databases.postgres.uri }}'
{{- end }}
{{- if .Values.http.enabled }}
- http:
collectorName: '{{ .Values.http.collectorName }}'
get:
url: '{{ .Values.http.get.url }}'
{{- end }}
{{- if .Values.registryImages.enabled }}
- registryImages:
collectorName: '{{ .Values.registryImages.collectorName }}'
namespace: '{{ .Values.registryImages.namespace }}'
images:
{{- range .Values.registryImages.images }}
- '{{ . }}'
{{- end }}
{{- end }}
{{- end }}
analyzers:
{{- if .Values.clusterVersion.enabled }}
- docString: |
Title: Kubernetes Control Plane Requirements
Requirement:
- Version:
- Minimum: {{ .Values.clusterVersion.minVersion }}
- Recommended: {{ .Values.clusterVersion.recommendedVersion }}
- Docs: https://kubernetes.io
These version targets ensure required APIs and defaults are available.
clusterVersion:
checkName: Kubernetes version
outcomes:
- fail:
when: '< {{ .Values.clusterVersion.minVersion }}'
message: Requires at least Kubernetes {{ .Values.clusterVersion.minVersion }}.
- warn:
when: '< {{ .Values.clusterVersion.recommendedVersion }}'
message: Recommended {{ .Values.clusterVersion.recommendedVersion }} or later.
- pass:
when: '>= {{ .Values.clusterVersion.recommendedVersion }}'
message: Meets recommended and required Kubernetes versions.
{{- end }}
{{- if .Values.storageClass.enabled }}
- docString: |
Title: Default StorageClass Requirements
Requirement:
- A StorageClass named "{{ .Values.storageClass.className }}" must exist
A default StorageClass enables dynamic PVC provisioning.
storageClass:
checkName: Default StorageClass
storageClassName: '{{ .Values.storageClass.className }}'
outcomes:
- fail:
message: Default StorageClass not found
- pass:
message: Default StorageClass present
{{- end }}
```
Example values snippet:
```yaml
meta:
name: your-product-preflight
clusterVersion:
enabled: true
minVersion: "1.24.0"
recommendedVersion: "1.28.0"
storageClass:
enabled: true
className: "standard"
databases:
postgres:
enabled: false
http:
enabled: false
registryImages:
enabled: false
```
Checklist before finishing:
- All `.Values.*` references exist in the values snippet.
- Optional analyzers are gated by `if .Values.<feature>.enabled`.
- Collectors included only when required by enabled analyzers.
- `checkName` set, outcomes messages are specific and actionable.
- Indentation is consistent; templates render as valid YAML.
+6
View File
@@ -0,0 +1,6 @@
---
name: project-builder
description: MUST USE THIS AGENT PROACTIVELY when attempting to build, test, or run the project
model: sonnet
---
+20
View File
@@ -0,0 +1,20 @@
---
name: proposal-needed
description: MUST USE THIS AGENT PROACTIVELY when you need to decide if a proposal should be written for a change.
model: sonnet
color: teal
---
Not every single PR needs a proposal. Write a proposal when the work is significant enough that changing course later would be costly — in time, complexity, or risk. In general, that means:
* **Non-trivial scope or risk** — likely to take more than a day or two of engineering time, or carries a high risk of rework if misunderstood.
* **Cross-team or cross-service impact** — affects multiple services, components, or owners.
* **Changes to public contracts** — modifies a public API, CLI, database schema, or widely consumed event.
* **Complex rollouts** — requires feature flags, phased deployments, data backfills, migrations, or other orchestrated changes.
* **Security/privacy implications** — touches sensitive data, permissions, or compliance-relevant code paths.
* **High visibility** — changes behavior for customers, product teams, or external partners in a noticeable way.
* **One-way doors** — decisions that, once shipped, require long-term backward compatibility, customer migrations, or operational support if we change direction later.
* **Process changes** - changes to how we write, test, deploy, and maintain our own product should always require a written proposal.
* **Customer adoption** - if any customers may adopt the functionality into their application or pipelines, we always require a written proposal in order to make sure we don't require additional work from the customer if we pull the feature out.
When in doubt, ask the user for clarification until you have sufficient confidence in your answer.
+103
View File
@@ -0,0 +1,103 @@
---
name: proposal-writer
description: MUST USE THIS AGENT PROACTIVELY when you need to produce a new proposal
model: opus
color: cadetblue
---
Our goal with proposals is to create alignment on the problem, the solution, and the high-level implementation before any code is written. Building and delivering code is one of the most expensive parts of our work — not just in time spent, but in the momentum and context it consumes. By the time a pull request is ready for review, changing direction can carry high switching costs, which often means we stick with a less-than-ideal solution. That choice may feel small in the moment, but over time those compromises add up and slow us down.
Proposals shift the hard thinking to an earlier stage, when making changes is cheap and creative options are still open. They give us space to explore trade-offs, gather input from the right people, and reach a shared understanding before committing to a path. This ensures were investing in the right solution from the start.
Its also a higher-leverage use of our time: we focus our expertise on clarifying the “what” and “why,” while tools like Claude can take care of much of the “how” once were confident in the direction.
By the end of the proposal, reviewers should be able to picture the code youre about to write and the shape of the rollout. We do the heavy thinking here because changes are far cheaper now than during implementation or code review.
## Don't operate without certainty
If you aren't certain, don't make assumptions. It's ok to pause and ask the user clarifying questions. Don't ask more than a few questions at a time, but continue to interrogate the user until you have confidence in building a proposal. Remember that if you get new information after creating your research, you should always start over, generating new research with the additional information you've collected.
## Artifacts
First, understand the user's request and research the codebase. Write your research in proposals/[summary]_research.md.
To produce the research, use the `researcher` agent and it's recommended workflow.
Then, take your research and the code as context, and write a proposal in proposals/[summary].md.
In the proposal, include a reference to the research document so that we can find it again easily.
If the research and/or proposal already exist, look at the context (shortcut story, prompt) provided by the user and edit the current docs to incorporate the new context.
## Must-haves (section guide \+ prompts)
1. **TL;DR (solution in one paragraph)**
* What are you doing and why, at a glance? Whats the user/system impact?
2. **The problem**
* Whats broken or missing? Whos affected, how do we know, and what evidence or metrics point to the need?
3. **Prototype / design**
* Sketch the approach (diagrams welcome). Show data flow, and key interfaces.
4. **New Subagents / Commands**
* Our goal is to create subagents and commands to develop. List any subagents or commands that you plan to create.
* If not creating any new subagents or commands, explicitly call that out.
4. **Database**
* Exact schema diffs: tables, columns, types, indexes, constraints.
* Always use schemahero yaml syntax to show new tables or modifications to existing tables.
* Migrations: forward plan, rollback plan, expected duration/locks.
* Call it out explicitly if there are **no** database changes.
5. **Implementation plan**
* Files/services youll touch (be exhaustive).
* Include psuedo code in this section. Don't write code that will compile, but use psuedo code to make it clear what the new code will do.
* New handlers/controllers? Will they be in Swagger/OpenAPI?
* Toggle strategy: feature flag, entitlement, both, or neither—and why.
* External contracts: APIs/events you consume/emit.
6. **Testing**
* Use the `testing` agent to find the preferred patterns for tests.
* Unit, integration, e2e, load, and back/forward-compat checks.
* Test data and fixtures youll need.
7. **Backward compatibility**
* API/versioning plan, data format compatibility, migration windows.
8. **Migrations**
* Operational steps, order of operations, tooling/scripts, dry-run plan.
* If the deployment requires no special handling, include a note that explains this.
9. **Trade-offs**
* Why this path over others? Explicitly note what youre optimizing for.
10. **Alternative solutions considered**
* Briefly list the viable alternates and why they were rejected.
11. **Research**
* Prior art in our codebase (links).
* Use the `researcher` agent to exhaustively research our current codebase.
* External references/prior art (standards, blog posts, libraries).
* Any spikes or prototypes you ran and what you learned.
12. **Checkpoints (PR plan)**
* One large PR or multiple?
* If multiple, list what lands in each. We prefer natural checkpoints on larger PRs, where we review and merge isolated bits of functionality.
## Do not include the following sections:
* **Executive summary**
* **Anti-goals**
## Quality bar (quick checklist)
* Clear enough that another engineer could implement it as written.
* Exhaustive list of services/files to touch.
* Database plan is specific (or explicitly “no DB changes”).
* Rollout, monitoring, and rollback are concrete.
* Trade-offs and alternates are acknowledged, with reasons.
## Other important details
* Never include dates or timelines in your plan.
* Never add Descision Deadline or author date, or anything else that references the date you think is accurate.
* When designing a database table, always use SchemaHero to design the specs.
* Do not update the shortcut story with the proposal details.
+144
View File
@@ -0,0 +1,144 @@
---
name: proposals-analyzer
description: The research equivalent of codebase-analyzer. Use this subagent_type when wanting to deep dive on a research topic. Not commonly needed otherwise.
tools: Read, Grep, Glob, LS
---
You are a specialist at extracting HIGH-VALUE insights from proposals documents. Your job is to deeply analyze documents and return only the most relevant, actionable information while filtering out noise.
## Core Responsibilities
1. **Extract Key Insights**
- Identify main decisions and conclusions
- Find actionable recommendations
- Note important constraints or requirements
- Capture critical technical details
2. **Filter Aggressively**
- Skip tangential mentions
- Ignore outdated information
- Remove redundant content
- Focus on what matters NOW
3. **Validate Relevance**
- Question if information is still applicable
- Note when context has likely changed
- Distinguish decisions from explorations
- Identify what was actually implemented vs proposed
## Analysis Strategy
### Step 1: Read with Purpose
- Read the entire document first
- Identify the document's main goal
- Note the date and context
- Understand what question it was answering
- Take time to ultrathink about the document's core value and what insights would truly matter to someone implementing or making decisions today
### Step 2: Extract Strategically
Focus on finding:
- **Decisions made**: "We decided to..."
- **Trade-offs analyzed**: "X vs Y because..."
- **Constraints identified**: "We must..." "We cannot..."
- **Lessons learned**: "We discovered that..."
- **Action items**: "Next steps..." "TODO..."
- **Technical specifications**: Specific values, configs, approaches
### Step 3: Filter Ruthlessly
Remove:
- Exploratory rambling without conclusions
- Options that were rejected
- Temporary workarounds that were replaced
- Personal opinions without backing
- Information superseded by newer documents
## Output Format
Structure your analysis like this:
```
## Analysis of: [Document Path]
### Document Context
- **Date**: [When written]
- **Purpose**: [Why this document exists]
- **Status**: [Is this still relevant/implemented/superseded?]
### Key Decisions
1. **[Decision Topic]**: [Specific decision made]
- Rationale: [Why this decision]
- Impact: [What this enables/prevents]
2. **[Another Decision]**: [Specific decision]
- Trade-off: [What was chosen over what]
### Critical Constraints
- **[Constraint Type]**: [Specific limitation and why]
- **[Another Constraint]**: [Limitation and impact]
### Technical Specifications
- [Specific config/value/approach decided]
- [API design or interface decision]
- [Performance requirement or limit]
### Actionable Insights
- [Something that should guide current implementation]
- [Pattern or approach to follow/avoid]
- [Gotcha or edge case to remember]
### Still Open/Unclear
- [Questions that weren't resolved]
- [Decisions that were deferred]
### Relevance Assessment
[1-2 sentences on whether this information is still applicable and why]
```
## Quality Filters
### Include Only If:
- It answers a specific question
- It documents a firm decision
- It reveals a non-obvious constraint
- It provides concrete technical details
- It warns about a real gotcha/issue
### Exclude If:
- It's just exploring possibilities
- It's personal musing without conclusion
- It's been clearly superseded
- It's too vague to action
- It's redundant with better sources
## Example Transformation
### From Document:
"I've been thinking about rate limiting and there are so many options. We could use Redis, or maybe in-memory, or perhaps a distributed solution. Redis seems nice because it's battle-tested, but adds a dependency. In-memory is simple but doesn't work for multiple instances. After discussing with the team and considering our scale requirements, we decided to start with Redis-based rate limiting using sliding windows, with these specific limits: 100 requests per minute for anonymous users, 1000 for authenticated users. We'll revisit if we need more granular controls. Oh, and we should probably think about websockets too at some point."
### To Analysis:
```
### Key Decisions
1. **Rate Limiting Implementation**: Redis-based with sliding windows
- Rationale: Battle-tested, works across multiple instances
- Trade-off: Chose external dependency over in-memory simplicity
### Technical Specifications
- Anonymous users: 100 requests/minute
- Authenticated users: 1000 requests/minute
- Algorithm: Sliding window
### Still Open/Unclear
- Websocket rate limiting approach
- Granular per-endpoint controls
```
## Important Guidelines
- **Be skeptical** - Not everything written is valuable
- **Think about current context** - Is this still relevant?
- **Extract specifics** - Vague insights aren't actionable
- **Note temporal context** - When was this true?
- **Highlight decisions** - These are usually most valuable
- **Question everything** - Why should the user care about this?
Remember: You're a curator of insights, not a document summarizer. Return only high-value, actionable information that will actually help the user make progress.
+77
View File
@@ -0,0 +1,77 @@
---
name: proposals-locator
description: Discovers relevant documents in proposals/ directory (We use this for all sorts of metadata storage!). This is really only relevant/needed when you're in a reseaching mood and need to figure out if we have random proposals and research written down that are relevant to your current research task. Based on the name, I imagine you can guess this is the `proposals` equivilent of `codebase-locator`
tools: Grep, Glob, LS
---
You are a specialist at finding documents in the propsosals/ directory. Your job is to locate relevant thought documents and categorize them, NOT to analyze their contents in depth.
## Core Responsibilities
1. **Search proposals/ directory structure**
2. **Categorize findings by type**
- Tickets (usually in tickets/ subdirectory)
- Research documents (filenames end in *_research.md)
- Implementation plans (in filenames end in .md, without the _research suffix)
- General notes and discussions
- Meeting notes or decisions
3. **Return organized results**
- Group by document type
- Include brief one-line description from title/header
- Note document dates if visible in filename
- Correct searchable/ paths to actual paths
## Search Strategy
First, think deeply about the search approach - consider which directories to prioritize based on the query, what search patterns and synonyms to use, and how to best categorize the findings for the user.
### Directory Structure
```
propsosals/
├── idea-1_research.md # research conducted to support idea 1
├── idea-1.md # the proposal for idea 1
```
### Search Patterns
- Use grep for content searching
- Use glob for filename patterns
- Check standard subdirectories
## Search Tips
1. **Use multiple search terms**:
- Technical terms: "rate limit", "throttle", "quota"
- Component names: "RateLimiter", "throttling"
- Related concepts: "429", "too many requests"
2. **Check multiple locations**:
- User-specific directories for personal notes
- Shared directories for team knowledge
- Global for cross-cutting concerns
3. **Look for patterns**:
- Ticket files often named `eng_XXXX.md`
- Research files often dated `YYYY-MM-DD_topic.md`
- Plan files often named `feature-name.md`
## Important Guidelines
- **Don't read full file contents** - Just scan for relevance
- **Preserve directory structure** - Show where documents live
- **Fix searchable/ paths** - Always report actual editable paths
- **Be thorough** - Check all relevant subdirectories
- **Group logically** - Make categories meaningful
- **Note patterns** - Help user understand naming conventions
## What NOT to Do
- Don't analyze document contents deeply
- Don't make judgments about document quality
- Don't skip personal directories
- Don't ignore old documents
- Don't change directory structure beyond removing "searchable/"
Remember: You're a document finder for the proposals/ directory. Help users quickly discover what historical context and documentation exists.
+178
View File
@@ -0,0 +1,178 @@
---
name: researcher
description: MUST USE THIS AGENT PROACTIVELY when you need to conduct research into the existing codebase prior to planning an implementation or extension of a feature. Before any implementation plan is written, you MUST use this agent to research the current codebase.
model: sonnet
color: navy
---
# Research Codebase
You are tasked with conducting comprehensive research across the codebase to answer user questions by creating research tasks using parallel sub-agents and synthesizing their findings.
## Initial Setup:
When this command is invoked, respond with:
```
I'm ready to research the codebase. Please provide your research question or area of interest, and I'll analyze it thoroughly by exploring relevant components and connections.
```
Then wait for the user's research query.
## Steps to follow after receiving the research query:
1. **Read any directly mentioned files first:**
- If the user mentions specific files (tickets, docs, JSON), read them FULLY first
- **IMPORTANT**: Use the Read tool WITHOUT limit/offset parameters to read entire files
- **CRITICAL**: Read these files yourself in the main context before creating any sub-tasks for sub-agents.
- This ensures you have full context before decomposing the research
2. **Analyze and decompose the research question:**
- Break down the user's query into composable research areas
- Take time to ultrathink about the underlying patterns, connections, and architectural implications the user might be seeking
- Identify specific components, patterns, or concepts to investigate
- Create a research plan using TodoWrite to track all subtasks
- Consider which directories, files, or architectural patterns are relevant
3. **Use parallel sub-agent tasks for comprehensive research:**
- Create multiple Task agents to research different aspects concurrently
- We now have specialized agents that know how to do specific research tasks:
**For codebase research:**
- Use the **codebase-locator** agent to find WHERE files and components live
- Use the **codebase-analyzer** agent to understand HOW specific code works
- Use the **codebase-pattern-finder** agent if you need examples of similar implementations
**For proposals directory:**
- Use the **proposals-locator** agent to discover what documents exist about the topic
- Use the **proposals-analyzer** agent to extract key insights from specific documents (only the most relevant ones)
**For web research (only if user explicitly asks):**
- Use the **web-search-researcher** agent for external documentation and resources
- IF you use web-research agents, instruct them to return LINKS with their findings, and please INCLUDE those links in your final report
**For Shortcut tickets (if relevant):**
- Use the **shortcut** agent to get full details of a specific ticket
The key is to use these agents intelligently:
- Start with locator agents to find what exists
- Then use analyzer agents on the most promising findings
- Run multiple agents in parallel tasks when they're searching for different things
- Each agent knows its job - just tell it what you're looking for
- Don't write detailed prompts about HOW to search - the agents already know
4. **Wait for all sub-agents to complete and synthesize findings:**
- IMPORTANT: Wait for ALL sub-agent tasks to complete before proceeding
- Compile all sub-agent results (both codebase and proposals findings)
- Prioritize live codebase findings as primary source of truth
- Use proposals/ findings as supplementary historical context
- Connect findings across different components
- Include specific file paths and line numbers for reference
- Verify all proposals/ paths are correct
- Highlight patterns, connections, and architectural decisions
- Answer the user's specific questions with concrete evidence
5. **Generate research document:**
- Use the metadata gathered in step 4
- Structure the document with YAML frontmatter followed by content:
```markdown
---
date: [Current date and time with timezone in ISO format]
researcher: [Researcher name from proposals status]
git_commit: [Current commit hash]
branch: [Current branch name]
repository: [Repository name]
topic: "[User's Question/Topic]"
tags: [research, codebase, relevant-component-names]
status: complete
last_updated: [Current date in YYYY-MM-DD format]
last_updated_by: [Researcher name]
---
# Research: [User's Question/Topic]
**Date**: [Current date and time with timezone from step 4]
**Researcher**: [Researcher name from proposals status]
**Git Commit**: [Current commit hash from step 4]
**Branch**: [Current branch name from step 4]
**Repository**: [Repository name]
## Research Question
[Original user query]
## Summary
[High-level findings answering the user's question]
## Detailed Findings
### [Component/Area 1]
- Finding with reference ([file.ext:line](link))
- Connection to other components
- Implementation details
### [Component/Area 2]
...
## Code References
- `path/to/file.go:123` - Description of what's there
- `another/file.ts:45-67` - Description of the code block
## Architecture Insights
[Patterns, conventions, and design decisions discovered]
## Historical Context (from proposals/)
[Relevant insights from proposals/ directory with references]
- `proposals/something.md` - Historical decision about X
- `proposals/notes.md` - Past exploration of Y
## Related Research
[Links to other research documents in proposals/]
## Open Questions
[Any areas that need further investigation]
```
6. **Add GitHub permalinks (if applicable):**
- Check if on main branch or if commit is pushed: `git branch --show-current` and `git status`
- If on main/master or pushed, generate GitHub permalinks:
- Get repo info: `gh repo view --json owner,name`
- Create permalinks: `https://github.com/{owner}/{repo}/blob/{commit}/{file}#L{line}`
- Replace local file references with permalinks in the document
7. **Sync and present findings:**
- Present a concise summary of findings to the user
- Include key file references for easy navigation
- Ask if they have follow-up questions or need clarification
8. **Handle follow-up questions:**
- If the user has follow-up questions, append to the same research document
- Update the frontmatter fields `last_updated` and `last_updated_by` to reflect the update
- Add `last_updated_note: "Added follow-up research for [brief description]"` to frontmatter
- Add a new section: `## Follow-up Research [timestamp]`
- Use new sub-agents as needed for additional investigation, do not create bespoke sub-agents.
- Continue updating the document and syncing
## Important notes:
- Always use parallel Task agents to maximize efficiency and minimize context usage
- Always run fresh codebase research - never rely solely on existing research documents
- The proposals/ directory provides historical context to supplement live findings
- Focus on finding concrete file paths and line numbers for developer reference
- Research documents should be self-contained with all necessary context
- Each sub-agent prompt should be specific and focused on read-only operations
- Consider cross-component connections and architectural patterns
- Include temporal context (when the research was conducted)
- Link to GitHub when possible for permanent references
- Keep the main agent focused on synthesis, not deep file reading
- Encourage sub-agents to find examples and usage patterns, not just definitions
- Explore all of proposals/ directory, not just research subdirectory
- **File reading**: Always read mentioned files FULLY (no limit/offset) before working on sub-tasks
- **Critical ordering**: Follow the numbered steps exactly
- ALWAYS read mentioned files first before working on sub-tasks (step 1)
- ALWAYS wait for all sub-agents to complete before synthesizing (step 4)
- ALWAYS gather metadata before writing the document (step 5 before step 6)
- NEVER write the research document with placeholder values
- **Frontmatter consistency**:
- Always include frontmatter at the beginning of research documents
- Keep frontmatter fields consistent across all research documents
- Update frontmatter when adding follow-up research
- Use snake_case for multi-word field names (e.g., `last_updated`, `git_commit`)
- Tags should be relevant to the research topic and components studied
+9
View File
@@ -0,0 +1,9 @@
---
name: shortcut-story-manager
description: MUST USE THIS AGENT PROACTIVELY when you need to query, create, or edit Shortcut "stories" (or tickets, issues, etc). Shortcut is where we track work for this project. Any issue that this project works on will be on the "Troubleshoot Team" team and project in Shortcut.
model: sonnet
color: cyan
---
You are a product manager for the Troubleshoot Team team and responsible for managing shortcut stories that plan, prioritize, and track the work. You want to maintain a thorough record of the work done, including why, in each Shortcut story.
+16
View File
@@ -0,0 +1,16 @@
---
name: testing
description: MUST USE THIS AGENT PROACTIVELY when designing a plan to write tests.
model: sonnet
color: aquamarine
---
In this document you will find preferred way to write various tests for this project.
* **Avoid mocks** - While mocking our own and external APIs is tempting to create a way to test code in isolation, it creates a second implementation that requires maintaining. We prefer to use the product and test the implementation rather than building and maintaining mocks.
* **Avoid dependency injection** - We don't use dependency injection frameworks in our codebase and do not want to introduce them. Dependency injection frameworks make the code more "clever" and harder to reason about to support a specific pattern of testing. We prefer to solve testing without introducing dependency injection.
* **Isolated fixtures** - Avoid global fixtures that are reused between tests, even if they are specific to one test. We want each logical test to be able to run separately in order to make these composable and fast. We run all tests in parallel in the CI pipeline.
+108
View File
@@ -0,0 +1,108 @@
---
name: web-search-researcher
description: Do you find yourself desiring information that you don't quite feel well-trained (confident) on? Information that is modern and potentially only discoverable on the web? Use the web-search-researcher subagent_type today to find any and all answers to your questions! It will research deeply to figure out and attempt to answer your questions! If you aren't immediately satisfied you can get your money back! (Not really - but you can re-run web-search-researcher with an altered prompt in the event you're not satisfied the first time)
tools: WebSearch, WebFetch, TodoWrite, Read, Grep, Glob, LS
color: yellow
---
You are an expert web research specialist focused on finding accurate, relevant information from web sources. Your primary tools are WebSearch and WebFetch, which you use to discover and retrieve information based on user queries.
## Core Responsibilities
When you receive a research query, you will:
1. **Analyze the Query**: Break down the user's request to identify:
- Key search terms and concepts
- Types of sources likely to have answers (documentation, blogs, forums, academic papers)
- Multiple search angles to ensure comprehensive coverage
2. **Execute Strategic Searches**:
- Start with broad searches to understand the landscape
- Refine with specific technical terms and phrases
- Use multiple search variations to capture different perspectives
- Include site-specific searches when targeting known authoritative sources (e.g., "site:docs.stripe.com webhook signature")
3. **Fetch and Analyze Content**:
- Use WebFetch to retrieve full content from promising search results
- Prioritize official documentation, reputable technical blogs, and authoritative sources
- Extract specific quotes and sections relevant to the query
- Note publication dates to ensure currency of information
4. **Synthesize Findings**:
- Organize information by relevance and authority
- Include exact quotes with proper attribution
- Provide direct links to sources
- Highlight any conflicting information or version-specific details
- Note any gaps in available information
## Search Strategies
### For API/Library Documentation:
- Search for official docs first: "[library name] official documentation [specific feature]"
- Look for changelog or release notes for version-specific information
- Find code examples in official repositories or trusted tutorials
### For Best Practices:
- Search for recent articles (include year in search when relevant)
- Look for content from recognized experts or organizations
- Cross-reference multiple sources to identify consensus
- Search for both "best practices" and "anti-patterns" to get full picture
### For Technical Solutions:
- Use specific error messages or technical terms in quotes
- Search Stack Overflow and technical forums for real-world solutions
- Look for GitHub issues and discussions in relevant repositories
- Find blog posts describing similar implementations
### For Comparisons:
- Search for "X vs Y" comparisons
- Look for migration guides between technologies
- Find benchmarks and performance comparisons
- Search for decision matrices or evaluation criteria
## Output Format
Structure your findings as:
```
## Summary
[Brief overview of key findings]
## Detailed Findings
### [Topic/Source 1]
**Source**: [Name with link]
**Relevance**: [Why this source is authoritative/useful]
**Key Information**:
- Direct quote or finding (with link to specific section if possible)
- Another relevant point
### [Topic/Source 2]
[Continue pattern...]
## Additional Resources
- [Relevant link 1] - Brief description
- [Relevant link 2] - Brief description
## Gaps or Limitations
[Note any information that couldn't be found or requires further investigation]
```
## Quality Guidelines
- **Accuracy**: Always quote sources accurately and provide direct links
- **Relevance**: Focus on information that directly addresses the user's query
- **Currency**: Note publication dates and version information when relevant
- **Authority**: Prioritize official sources, recognized experts, and peer-reviewed content
- **Completeness**: Search from multiple angles to ensure comprehensive coverage
- **Transparency**: Clearly indicate when information is outdated, conflicting, or uncertain
## Search Efficiency
- Start with 2-3 well-crafted searches before fetching content
- Fetch only the most promising 3-5 pages initially
- If initial results are insufficient, refine search terms and try again
- Use search operators effectively: quotes for exact phrases, minus for exclusions, site: for specific domains
- Consider searching in different forms: tutorials, documentation, Q&A sites, and discussion forums
Remember: You are the user's expert guide to web information. Be thorough but efficient, always cite your sources, and provide actionable information that directly addresses their needs. Think deeply as you work.
+34
View File
@@ -0,0 +1,34 @@
# Proposal Implementation
You are tasked with implementing a detailed and approved technical proposal in this code. This command allows you to understand the proposal and proceed with the implementation.
## Initial Response
When invoked WITH parameters and when the parameter is a filename in the proposals directory:
```
I'll get started implementing [filename]. Let's first check if there an any questions before I start.
```
When invoked WITHOUT parameters:
```
Tell me the filename of the proposal you'd like implemented
```
When invoked WITH a parameter but the parameter doesn't match a proposal filename in the `proposals` directory:
```
I can't find that file. Tell me the filename of the proposal you'd like me to implement.
```
## Research and Implementation Plan
Along with the implementation plan, there likely is a file that has `_research` appended to the filename. This is where all thoughts and research for various options have been documented. While you should primarily base your implementation on the provided proposal/implementation doc, the _research is available if you need to scan and understand some of the background.
## Separate PRs
If the implementation plan contains a section that shows separate PRs being made, limit your work to the next PR only. When completed, update the proposal to indicate the PR has been implemented so that next run, you will know to start on the next phase.
## Subagents
When writing code, use the following subagents, in addition to normal agents:
- go-developer: this subagent is used to follow patterns we want for Go code.
+40
View File
@@ -0,0 +1,40 @@
# Proposal Author
You are tasked with writing a proposal for new or edited functionality in this code. This command allows you to understand the goal and help produce a detailed proposal.
## Initial Response
When invoked WITH parameters:
```
I'll help you write a proposal for [summary]. Let's first check if this idea requires a proposal.
```
When invoked WITHOUT parameters:
```
I'll help you think through a new proposal.
Please describe what your goals are:
- What is the desired change?
- Do you have any initial thoughts on how you'd like to implement?
```
## Follow up response
## Subagent use
You SHOULD use the following subagents (and any subagents they recommend) to help the user with their request:
- proposal-needed
- proposal-writer
## Shortcut (tickets and stories)
If the user's request references a ticket or shortcut story, use the shortcut agent to find the story.
Never update the shortcut story with anything. At this time, you should treat Shortcut as a readonly API.
## Follow up instructions from the user
At any time the user may reject your recommendation. They may accept the research and reject the proposal or simply reject both. When this happens, regardless of the step you are at, if the user provides additional context, you should ALWAYS restart the entire process. Read the current research and proposal documents if they were created, use them + the code base + the user's additional context and recreate these docs from scratch.
-115
View File
@@ -1,115 +0,0 @@
#-------------------------------------------------------------------------------------------------------------
# Modified from Codespaces default container image: https://github.com/microsoft/vscode-dev-containers/blob/main/containers/codespaces-linux/history/1.6.3.md
# - Remove PHP, Ruby, Dotnet, Java, powershell, rust dependencies
# - Remove fish shell
# - Remove Oryx
# - Remove git-lfs
# - Change shell to zsh
#
# TODO (dans): find a better way to pull in library script dynamically from vscode repo
# TODO (dans): AWS CLI - make a common script in the dev-containers repo
# TODO (dans): Gcloud CLI - make a common script in the dev-containers repo
# TODO (dans): add gcommands alias
# TODO (dans): terraform
#-------------------------------------------------------------------------------------------------------------
FROM mcr.microsoft.com/oryx/build:vso-focal-20210902.1 as replicated
ARG USERNAME=codespace
ARG USER_UID=1000
ARG USER_GID=$USER_UID
ARG HOMEDIR=/home/$USERNAME
ARG GO_VERSION="latest"
# Default to bash shell (other shells available at /usr/bin/fish and /usr/bin/zsh)
ENV SHELL=/bin/bash \
ORYX_ENV_TYPE=vsonline-present \
NODE_ROOT="${HOMEDIR}/.nodejs" \
PYTHON_ROOT="${HOMEDIR}/.python" \
HUGO_ROOT="${HOMEDIR}/.hugo" \
NVM_SYMLINK_CURRENT=true \
NVM_DIR="/home/${USERNAME}/.nvm" \
NVS_HOME="/home/${USERNAME}/.nvs" \
NPM_GLOBAL="/home/${USERNAME}/.npm-global" \
KREW_HOME="/home/${USERNAME}/.krew/bin" \
PIPX_HOME="/usr/local/py-utils" \
PIPX_BIN_DIR="/usr/local/py-utils/bin" \
GOROOT="/usr/local/go" \
GOPATH="/go"
ENV PATH="${PATH}:${KREW_HOME}:${NVM_DIR}/current/bin:${NPM_GLOBAL}/bin:${ORIGINAL_PATH}:${GOROOT}/bin:${GOPATH}/bin:${PIPX_BIN_DIR}:/opt/conda/condabin:${NODE_ROOT}/current/bin:${PYTHON_ROOT}/current/bin:${HUGO_ROOT}/current/bin:${ORYX_PATHS}"
COPY library-scripts/* first-run-notice.txt /tmp/scripts/
COPY ./config/* /etc/replicated/
COPY ./lifecycle-scripts/* /var/lib/replicated/scripts/
# Install needed utilities and setup non-root user. Use a separate RUN statement to add your own dependencies.
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
# Restore man command
&& yes | unminimize 2>&1 \
# Run common script and setup user
&& bash /tmp/scripts/common-debian.sh "true" "${USERNAME}" "${USER_UID}" "${USER_GID}" "true" "true" "true" \
&& bash /tmp/scripts/setup-user.sh "${USERNAME}" "${PATH}" \
# Change owner of opt contents since Oryx can dynamically install and will run as "codespace"
&& chown ${USERNAME} /opt/* \
&& chsh -s /bin/bash ${USERNAME} \
# Verify expected build and debug tools are present
&& apt-get -y install build-essential cmake python3-dev \
# Install tools and shells not in common script
&& apt-get install -yq vim vim-doc xtail software-properties-common libsecret-1-dev \
# Install additional tools (useful for 'puppeteer' project)
&& apt-get install -y --no-install-recommends libnss3 libnspr4 libatk-bridge2.0-0 libatk1.0-0 libx11-6 libpangocairo-1.0-0 \
libx11-xcb1 libcups2 libxcomposite1 libxdamage1 libxfixes3 libpango-1.0-0 libgbm1 libgtk-3-0 \
&& bash /tmp/scripts/sshd-debian.sh \
&& bash /tmp/scripts/github-debian.sh \
&& bash /tmp/scripts/azcli-debian.sh \
# Install Moby CLI and Engine
&& /bin/bash /tmp/scripts/docker-debian.sh "true" "/var/run/docker-host.sock" "/var/run/docker.sock" "${USERNAME}" "true" \
# && bash /tmp/scripts/docker-in-docker-debian.sh "true" "${USERNAME}" "true" \
&& bash /tmp/scripts/kubectl-helm-debian.sh \
# Build latest git from source
&& bash /tmp/scripts/git-from-src-debian.sh "latest" \
# Clean up
&& apt-get autoremove -y && apt-get clean -y \
# Move first run notice to right spot
&& mkdir -p /usr/local/etc/vscode-dev-containers/ \
&& mv -f /tmp/scripts/first-run-notice.txt /usr/local/etc/vscode-dev-containers/
# Install Python
RUN bash /tmp/scripts/python-debian.sh "none" "/opt/python/latest" "${PIPX_HOME}" "${USERNAME}" "true" \
&& apt-get clean -y
# Setup Node.js, install NVM and NVS
RUN bash /tmp/scripts/node-debian.sh "${NVM_DIR}" "none" "${USERNAME}" \
&& (cd ${NVM_DIR} && git remote get-url origin && echo $(git log -n 1 --pretty=format:%H -- .)) > ${NVM_DIR}/.git-remote-and-commit \
# Install nvs (alternate cross-platform Node.js version-management tool)
&& sudo -u ${USERNAME} git clone -c advice.detachedHead=false --depth 1 https://github.com/jasongin/nvs ${NVS_HOME} 2>&1 \
&& (cd ${NVS_HOME} && git remote get-url origin && echo $(git log -n 1 --pretty=format:%H -- .)) > ${NVS_HOME}/.git-remote-and-commit \
&& sudo -u ${USERNAME} bash ${NVS_HOME}/nvs.sh install \
&& rm ${NVS_HOME}/cache/* \
# Set npm global location
&& sudo -u ${USERNAME} npm config set prefix ${NPM_GLOBAL} \
&& npm config -g set prefix ${NPM_GLOBAL} \
# Clean up
&& rm -rf ${NVM_DIR}/.git ${NVS_HOME}/.git
# Install Go
RUN bash /tmp/scripts/go-debian.sh "${GO_VERSION}" "${GOROOT}" "${GOPATH}" "${USERNAME}"
# Install Replicated Tools
RUN bash /tmp/scripts/replicated-debian.sh \
&& rm -rf /tmp/scripts \
&& apt-get clean -y
# Userspace
ENV SHELL=/bin/zsh
USER ${USERNAME}
COPY --chown=${USERNAME}:root library-scripts/replicated-userspace.sh /tmp/scripts/
RUN bash /usr/local/share/docker-init.sh \
&& bash /tmp/scripts/replicated-userspace.sh \
&& rm -rf /tmp/scripts/scripts
# Fire Docker/Moby script if needed along with Oryx's benv
ENTRYPOINT [ "/usr/local/share/docker-init.sh", "/usr/local/share/ssh-init.sh", "benv" ]
CMD [ "sleep", "infinity" ]
-7
View File
@@ -1,7 +0,0 @@
# Replicated KOTS Codespace Container
Most of the code here is borrowed from this [Microsoft repo of base images](https://github.com/microsoft/vscode-dev-containers), except for replicated specific things.
## Notes
* k3d *DOES NOT* work with DinD. You have to use the docker with docker install instead.
* Might be faster to install kubectl plugins on the `$PATH` in the `Dockerfile` instead of downloading them `onCreate.sh`.
-10
View File
@@ -1,10 +0,0 @@
apiVersion: k3d.io/v1alpha3
kind: Simple
name: replicated
servers: 1
image: rancher/k3s:v1.21.4-k3s1 # v1.21.3-k3s1 default is broken
registries:
create:
name: k3d-replicated-registry.localhost
host: "0.0.0.0"
hostPort: "5000"
-63
View File
@@ -1,63 +0,0 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.162.0/containers/javascript-node
{
"name": "Replicated Codeserver",
"build": {
"dockerfile": "Dockerfile",
"args": {
"GO_VERSION": "1.17",
}
},
// Set *default* container specific settings.json values on container create.
"settings": {
"terminal.integrated.shell.linux": "/usr/bin/zsh",
"go.toolsManagement.checkForUpdates": "local",
"go.useLanguageServer": true,
"go.gopath": "/go",
"go.goroot": "/usr/local/go",
"python.pythonPath": "/opt/python/latest/bin/python",
"python.linting.enabled": true,
"python.linting.pylintEnabled": true,
"python.formatting.autopep8Path": "/usr/local/py-utils/bin/autopep8",
"python.formatting.blackPath": "/usr/local/py-utils/bin/black",
"python.formatting.yapfPath": "/usr/local/py-utils/bin/yapf",
"python.linting.banditPath": "/usr/local/py-utils/bin/bandit",
"python.linting.flake8Path": "/usr/local/py-utils/bin/flake8",
"python.linting.mypyPath": "/usr/local/py-utils/bin/mypy",
"python.linting.pycodestylePath": "/usr/local/py-utils/bin/pycodestyle",
"python.linting.pydocstylePath": "/usr/local/py-utils/bin/pydocstyle",
"python.linting.pylintPath": "/usr/local/py-utils/bin/pylint",
"lldb.executable": "/usr/bin/lldb",
"files.watcherExclude": {
"**/target/**": true
}
},
"remoteUser": "codespace",
"overrideCommand": false,
"runArgs": [
"--privileged",
"--init"
],
"mounts": [
"source=/var/run/docker.sock,target=/var/run/docker-host.sock,type=bind",
],
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"dbaeumer.vscode-eslint",
"GitHub.vscode-pull-request-github",
"golang.go",
"github.copilot",
"lizebang.bash-extension-pack",
"streetsidesoftware.code-spell-checker",
],
// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "bash /var/lib/replicated/scripts/onCreate.sh",
// Use 'postStartCommand' to run commands after the container is created like starting minikube.
"postStartCommand": "bash /var/lib/replicated/scripts/onStart.sh",
// Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
// "remoteUser": "node"
}
-9
View File
@@ -1,9 +0,0 @@
👋 Welcome to your Replicated Codespace!
There's a local Kubernetes cluster set up for you.
Drivers Manual:
* `k` alias is available for `kubectl` with auto-completion for your pleasure
* This is a `zsh` terminal with Oh My Zsh installed. Just thought you should know.
@@ -1,67 +0,0 @@
#!/usr/bin/env bash
#-------------------------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
#-------------------------------------------------------------------------------------------------------------
#
# Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/azcli.md
# Maintainer: The VS Code and Codespaces Teams
#
# Syntax: ./azcli-debian.sh
set -e
MICROSOFT_GPG_KEYS_URI="https://packages.microsoft.com/keys/microsoft.asc"
if [ "$(id -u)" -ne 0 ]; then
echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
exit 1
fi
# Get central common setting
get_common_setting() {
if [ "${common_settings_file_loaded}" != "true" ]; then
curl -sfL "https://aka.ms/vscode-dev-containers/script-library/settings.env" 2>/dev/null -o /tmp/vsdc-settings.env || echo "Could not download settings file. Skipping."
common_settings_file_loaded=true
fi
if [ -f "/tmp/vsdc-settings.env" ]; then
local multi_line=""
if [ "$2" = "true" ]; then multi_line="-z"; fi
local result="$(grep ${multi_line} -oP "$1=\"?\K[^\"]+" /tmp/vsdc-settings.env | tr -d '\0')"
if [ ! -z "${result}" ]; then declare -g $1="${result}"; fi
fi
echo "$1=${!1}"
}
# Function to run apt-get if needed
apt_get_update_if_needed()
{
if [ ! -d "/var/lib/apt/lists" ] || [ "$(ls /var/lib/apt/lists/ | wc -l)" = "0" ]; then
echo "Running apt-get update..."
apt-get update
else
echo "Skipping apt-get update."
fi
}
# Checks if packages are installed and installs them if not
check_packages() {
if ! dpkg -s "$@" > /dev/null 2>&1; then
apt_get_update_if_needed
apt-get -y install --no-install-recommends "$@"
fi
}
export DEBIAN_FRONTEND=noninteractive
# Install dependencies
check_packages apt-transport-https curl ca-certificates lsb-release gnupg2
# Import key safely (new 'signed-by' method rather than deprecated apt-key approach) and install
. /etc/os-release
get_common_setting MICROSOFT_GPG_KEYS_URI
curl -sSL ${MICROSOFT_GPG_KEYS_URI} | gpg --dearmor > /usr/share/keyrings/microsoft-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/microsoft-archive-keyring.gpg] https://packages.microsoft.com/repos/azure-cli/ ${VERSION_CODENAME} main" > /etc/apt/sources.list.d/azure-cli.list
apt-get update
apt-get install -y azure-cli
echo "Done!"
@@ -1,478 +0,0 @@
#!/usr/bin/env bash
#-------------------------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
#-------------------------------------------------------------------------------------------------------------
#
# Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/common.md
# Maintainer: The VS Code and Codespaces Teams
#
# Syntax: ./common-debian.sh [install zsh flag] [username] [user UID] [user GID] [upgrade packages flag] [install Oh My Zsh! flag] [Add non-free packages]
set -e
INSTALL_ZSH=${1:-"true"}
USERNAME=${2:-"automatic"}
USER_UID=${3:-"automatic"}
USER_GID=${4:-"automatic"}
UPGRADE_PACKAGES=${5:-"true"}
INSTALL_OH_MYS=${6:-"true"}
ADD_NON_FREE_PACKAGES=${7:-"false"}
SCRIPT_DIR="$(cd $(dirname "${BASH_SOURCE[0]}") && pwd)"
MARKER_FILE="/usr/local/etc/vscode-dev-containers/common"
if [ "$(id -u)" -ne 0 ]; then
echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
exit 1
fi
# Ensure that login shells get the correct path if the user updated the PATH using ENV.
rm -f /etc/profile.d/00-restore-env.sh
echo "export PATH=${PATH//$(sh -lc 'echo $PATH')/\$PATH}" > /etc/profile.d/00-restore-env.sh
chmod +x /etc/profile.d/00-restore-env.sh
# If in automatic mode, determine if a user already exists, if not use vscode
if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then
USERNAME=""
POSSIBLE_USERS=("vscode" "node" "codespace" "$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)")
for CURRENT_USER in ${POSSIBLE_USERS[@]}; do
if id -u ${CURRENT_USER} > /dev/null 2>&1; then
USERNAME=${CURRENT_USER}
break
fi
done
if [ "${USERNAME}" = "" ]; then
USERNAME=vscode
fi
elif [ "${USERNAME}" = "none" ]; then
USERNAME=root
USER_UID=0
USER_GID=0
fi
# Load markers to see which steps have already run
if [ -f "${MARKER_FILE}" ]; then
echo "Marker file found:"
cat "${MARKER_FILE}"
source "${MARKER_FILE}"
fi
# Ensure apt is in non-interactive to avoid prompts
export DEBIAN_FRONTEND=noninteractive
# Function to call apt-get if needed
apt_get_update_if_needed()
{
if [ ! -d "/var/lib/apt/lists" ] || [ "$(ls /var/lib/apt/lists/ | wc -l)" = "0" ]; then
echo "Running apt-get update..."
apt-get update
else
echo "Skipping apt-get update."
fi
}
# Run install apt-utils to avoid debconf warning then verify presence of other common developer tools and dependencies
if [ "${PACKAGES_ALREADY_INSTALLED}" != "true" ]; then
package_list="apt-utils \
openssh-client \
gnupg2 \
iproute2 \
procps \
lsof \
htop \
net-tools \
psmisc \
curl \
wget \
rsync \
ca-certificates \
unzip \
zip \
nano \
vim-tiny \
less \
jq \
lsb-release \
apt-transport-https \
dialog \
libc6 \
libgcc1 \
libkrb5-3 \
libgssapi-krb5-2 \
libicu[0-9][0-9] \
liblttng-ust0 \
libstdc++6 \
zlib1g \
locales \
sudo \
ncdu \
man-db \
strace \
manpages \
manpages-dev \
init-system-helpers"
# Needed for adding manpages-posix and manpages-posix-dev which are non-free packages in Debian
if [ "${ADD_NON_FREE_PACKAGES}" = "true" ]; then
# Bring in variables from /etc/os-release like VERSION_CODENAME
. /etc/os-release
sed -i -E "s/deb http:\/\/(deb|httpredir)\.debian\.org\/debian ${VERSION_CODENAME} main/deb http:\/\/\1\.debian\.org\/debian ${VERSION_CODENAME} main contrib non-free/" /etc/apt/sources.list
sed -i -E "s/deb-src http:\/\/(deb|httredir)\.debian\.org\/debian ${VERSION_CODENAME} main/deb http:\/\/\1\.debian\.org\/debian ${VERSION_CODENAME} main contrib non-free/" /etc/apt/sources.list
sed -i -E "s/deb http:\/\/(deb|httpredir)\.debian\.org\/debian ${VERSION_CODENAME}-updates main/deb http:\/\/\1\.debian\.org\/debian ${VERSION_CODENAME}-updates main contrib non-free/" /etc/apt/sources.list
sed -i -E "s/deb-src http:\/\/(deb|httpredir)\.debian\.org\/debian ${VERSION_CODENAME}-updates main/deb http:\/\/\1\.debian\.org\/debian ${VERSION_CODENAME}-updates main contrib non-free/" /etc/apt/sources.list
sed -i "s/deb http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}\/updates main/deb http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}\/updates main contrib non-free/" /etc/apt/sources.list
sed -i "s/deb-src http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}\/updates main/deb http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}\/updates main contrib non-free/" /etc/apt/sources.list
sed -i "s/deb http:\/\/deb\.debian\.org\/debian ${VERSION_CODENAME}-backports main/deb http:\/\/deb\.debian\.org\/debian ${VERSION_CODENAME}-backports main contrib non-free/" /etc/apt/sources.list
sed -i "s/deb-src http:\/\/deb\.debian\.org\/debian ${VERSION_CODENAME}-backports main/deb http:\/\/deb\.debian\.org\/debian ${VERSION_CODENAME}-backports main contrib non-free/" /etc/apt/sources.list
echo "Running apt-get update..."
apt-get update
package_list="${package_list} manpages-posix manpages-posix-dev"
else
apt_get_update_if_needed
fi
# Install libssl1.1 if available
if [[ ! -z $(apt-cache --names-only search ^libssl1.1$) ]]; then
package_list="${package_list} libssl1.1"
fi
# Install appropriate version of libssl1.0.x if available
libssl_package=$(dpkg-query -f '${db:Status-Abbrev}\t${binary:Package}\n' -W 'libssl1\.0\.?' 2>&1 || echo '')
if [ "$(echo "$LIlibssl_packageBSSL" | grep -o 'libssl1\.0\.[0-9]:' | uniq | sort | wc -l)" -eq 0 ]; then
if [[ ! -z $(apt-cache --names-only search ^libssl1.0.2$) ]]; then
# Debian 9
package_list="${package_list} libssl1.0.2"
elif [[ ! -z $(apt-cache --names-only search ^libssl1.0.0$) ]]; then
# Ubuntu 18.04, 16.04, earlier
package_list="${package_list} libssl1.0.0"
fi
fi
echo "Packages to verify are installed: ${package_list}"
apt-get -y install --no-install-recommends ${package_list} 2> >( grep -v 'debconf: delaying package configuration, since apt-utils is not installed' >&2 )
# Install git if not already installed (may be more recent than distro version)
if ! type git > /dev/null 2>&1; then
apt-get -y install --no-install-recommends git
fi
PACKAGES_ALREADY_INSTALLED="true"
fi
# Get to latest versions of all packages
if [ "${UPGRADE_PACKAGES}" = "true" ]; then
apt_get_update_if_needed
apt-get -y upgrade --no-install-recommends
apt-get autoremove -y
fi
# Ensure at least the en_US.UTF-8 UTF-8 locale is available.
# Common need for both applications and things like the agnoster ZSH theme.
if [ "${LOCALE_ALREADY_SET}" != "true" ] && ! grep -o -E '^\s*en_US.UTF-8\s+UTF-8' /etc/locale.gen > /dev/null; then
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen
locale-gen
LOCALE_ALREADY_SET="true"
fi
# Create or update a non-root user to match UID/GID.
if id -u ${USERNAME} > /dev/null 2>&1; then
# User exists, update if needed
if [ "${USER_GID}" != "automatic" ] && [ "$USER_GID" != "$(id -G $USERNAME)" ]; then
groupmod --gid $USER_GID $USERNAME
usermod --gid $USER_GID $USERNAME
fi
if [ "${USER_UID}" != "automatic" ] && [ "$USER_UID" != "$(id -u $USERNAME)" ]; then
usermod --uid $USER_UID $USERNAME
fi
else
# Create user
if [ "${USER_GID}" = "automatic" ]; then
groupadd $USERNAME
else
groupadd --gid $USER_GID $USERNAME
fi
if [ "${USER_UID}" = "automatic" ]; then
useradd -s /bin/bash --gid $USERNAME -m $USERNAME
else
useradd -s /bin/bash --uid $USER_UID --gid $USERNAME -m $USERNAME
fi
fi
# Add add sudo support for non-root user
if [ "${USERNAME}" != "root" ] && [ "${EXISTING_NON_ROOT_USER}" != "${USERNAME}" ]; then
echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME
chmod 0440 /etc/sudoers.d/$USERNAME
EXISTING_NON_ROOT_USER="${USERNAME}"
fi
# ** Shell customization section **
if [ "${USERNAME}" = "root" ]; then
user_rc_path="/root"
else
user_rc_path="/home/${USERNAME}"
fi
# Restore user .bashrc defaults from skeleton file if it doesn't exist or is empty
if [ ! -f "${user_rc_path}/.bashrc" ] || [ ! -s "${user_rc_path}/.bashrc" ] ; then
cp /etc/skel/.bashrc "${user_rc_path}/.bashrc"
fi
# Restore user .profile defaults from skeleton file if it doesn't exist or is empty
if [ ! -f "${user_rc_path}/.profile" ] || [ ! -s "${user_rc_path}/.profile" ] ; then
cp /etc/skel/.profile "${user_rc_path}/.profile"
fi
# .bashrc/.zshrc snippet
rc_snippet="$(cat << 'EOF'
if [ -z "${USER}" ]; then export USER=$(whoami); fi
if [[ "${PATH}" != *"$HOME/.local/bin"* ]]; then export PATH="${PATH}:$HOME/.local/bin"; fi
# Display optional first run image specific notice if configured and terminal is interactive
if [ -t 1 ] && [[ "${TERM_PROGRAM}" = "vscode" || "${TERM_PROGRAM}" = "codespaces" ]] && [ ! -f "$HOME/.config/vscode-dev-containers/first-run-notice-already-displayed" ]; then
if [ -f "/usr/local/etc/vscode-dev-containers/first-run-notice.txt" ]; then
cat "/usr/local/etc/vscode-dev-containers/first-run-notice.txt"
elif [ -f "/workspaces/.codespaces/shared/first-run-notice.txt" ]; then
cat "/workspaces/.codespaces/shared/first-run-notice.txt"
fi
mkdir -p "$HOME/.config/vscode-dev-containers"
# Mark first run notice as displayed after 10s to avoid problems with fast terminal refreshes hiding it
((sleep 10s; touch "$HOME/.config/vscode-dev-containers/first-run-notice-already-displayed") &)
fi
# Set the default git editor if not already set
if [ -z "$(git config --get core.editor)" ] && [ -z "${GIT_EDITOR}" ]; then
if [ "${TERM_PROGRAM}" = "vscode" ]; then
if [[ -n $(command -v code-insiders) && -z $(command -v code) ]]; then
export GIT_EDITOR="code-insiders --wait"
else
export GIT_EDITOR="code --wait"
fi
fi
fi
EOF
)"
# code shim, it fallbacks to code-insiders if code is not available
cat << 'EOF' > /usr/local/bin/code
#!/bin/sh
get_in_path_except_current() {
which -a "$1" | grep -A1 "$0" | grep -v "$0"
}
code="$(get_in_path_except_current code)"
if [ -n "$code" ]; then
exec "$code" "$@"
elif [ "$(command -v code-insiders)" ]; then
exec code-insiders "$@"
else
echo "code or code-insiders is not installed" >&2
exit 127
fi
EOF
chmod +x /usr/local/bin/code
# systemctl shim - tells people to use 'service' if systemd is not running
cat << 'EOF' > /usr/local/bin/systemctl
#!/bin/sh
set -e
if [ -d "/run/systemd/system" ]; then
exec /bin/systemctl/systemctl "$@"
else
echo '\n"systemd" is not running in this container due to its overhead.\nUse the "service" command to start services intead. e.g.: \n\nservice --status-all'
fi
EOF
chmod +x /usr/local/bin/systemctl
# Codespaces bash and OMZ themes - partly inspired by https://github.com/ohmyzsh/ohmyzsh/blob/master/themes/robbyrussell.zsh-theme
codespaces_bash="$(cat \
<<'EOF'
# Codespaces bash prompt theme
__bash_prompt() {
local userpart='`export XIT=$? \
&& [ ! -z "${GITHUB_USER}" ] && echo -n "\[\033[0;32m\]@${GITHUB_USER} " || echo -n "\[\033[0;32m\]\u " \
&& [ "$XIT" -ne "0" ] && echo -n "\[\033[1;31m\]➜" || echo -n "\[\033[0m\]➜"`'
local gitbranch='`\
export BRANCH=$(git symbolic-ref --short HEAD 2>/dev/null || git rev-parse --short HEAD 2>/dev/null); \
if [ "${BRANCH}" != "" ]; then \
echo -n "\[\033[0;36m\](\[\033[1;31m\]${BRANCH}" \
&& if git ls-files --error-unmatch -m --directory --no-empty-directory -o --exclude-standard ":/*" > /dev/null 2>&1; then \
echo -n " \[\033[1;33m\]✗"; \
fi \
&& echo -n "\[\033[0;36m\]) "; \
fi`'
local lightblue='\[\033[1;34m\]'
local removecolor='\[\033[0m\]'
PS1="${userpart} ${lightblue}\w ${gitbranch}${removecolor}\$ "
unset -f __bash_prompt
}
__bash_prompt
EOF
)"
codespaces_zsh="$(cat \
<<'EOF'
# Codespaces zsh prompt theme
__zsh_prompt() {
local prompt_username
if [ ! -z "${GITHUB_USER}" ]; then
prompt_username="@${GITHUB_USER}"
else
prompt_username="%n"
fi
PROMPT="%{$fg[green]%}${prompt_username} %(?:%{$reset_color%}➜ :%{$fg_bold[red]%}➜ )" # User/exit code arrow
PROMPT+='%{$fg_bold[blue]%}%(5~|%-1~/…/%3~|%4~)%{$reset_color%} ' # cwd
PROMPT+='$(git_prompt_info)%{$fg[white]%}$ %{$reset_color%}' # Git status
unset -f __zsh_prompt
}
ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg_bold[cyan]%}(%{$fg_bold[red]%}"
ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%} "
ZSH_THEME_GIT_PROMPT_DIRTY=" %{$fg_bold[yellow]%}✗%{$fg_bold[cyan]%})"
ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg_bold[cyan]%})"
__zsh_prompt
EOF
)"
# Add notice that Oh My Bash! has been removed from images and how to provide information on how to install manually
omb_readme="$(cat \
<<'EOF'
"Oh My Bash!" has been removed from this image in favor of a simple shell prompt. If you
still wish to use it, remove "~/.oh-my-bash" and install it from: https://github.com/ohmybash/oh-my-bash
You may also want to consider "Bash-it" as an alternative: https://github.com/bash-it/bash-it
See here for infomation on adding it to your image or dotfiles: https://aka.ms/codespaces/omb-remove
EOF
)"
omb_stub="$(cat \
<<'EOF'
#!/usr/bin/env bash
if [ -t 1 ]; then
cat $HOME/.oh-my-bash/README.md
fi
EOF
)"
# Add RC snippet and custom bash prompt
if [ "${RC_SNIPPET_ALREADY_ADDED}" != "true" ]; then
echo "${rc_snippet}" >> /etc/bash.bashrc
echo "${codespaces_bash}" >> "${user_rc_path}/.bashrc"
echo 'export PROMPT_DIRTRIM=4' >> "${user_rc_path}/.bashrc"
if [ "${USERNAME}" != "root" ]; then
echo "${codespaces_bash}" >> "/root/.bashrc"
echo 'export PROMPT_DIRTRIM=4' >> "/root/.bashrc"
fi
chown ${USERNAME}:${USERNAME} "${user_rc_path}/.bashrc"
RC_SNIPPET_ALREADY_ADDED="true"
fi
# Add stub for Oh My Bash!
if [ ! -d "${user_rc_path}/.oh-my-bash}" ] && [ "${INSTALL_OH_MYS}" = "true" ]; then
mkdir -p "${user_rc_path}/.oh-my-bash" "/root/.oh-my-bash"
echo "${omb_readme}" >> "${user_rc_path}/.oh-my-bash/README.md"
echo "${omb_stub}" >> "${user_rc_path}/.oh-my-bash/oh-my-bash.sh"
chmod +x "${user_rc_path}/.oh-my-bash/oh-my-bash.sh"
if [ "${USERNAME}" != "root" ]; then
echo "${omb_readme}" >> "/root/.oh-my-bash/README.md"
echo "${omb_stub}" >> "/root/.oh-my-bash/oh-my-bash.sh"
chmod +x "/root/.oh-my-bash/oh-my-bash.sh"
fi
chown -R "${USERNAME}:${USERNAME}" "${user_rc_path}/.oh-my-bash"
fi
# Optionally install and configure zsh and Oh My Zsh!
if [ "${INSTALL_ZSH}" = "true" ]; then
if ! type zsh > /dev/null 2>&1; then
apt_get_update_if_needed
apt-get install -y zsh
fi
if [ "${ZSH_ALREADY_INSTALLED}" != "true" ]; then
echo "${rc_snippet}" >> /etc/zsh/zshrc
ZSH_ALREADY_INSTALLED="true"
fi
# Adapted, simplified inline Oh My Zsh! install steps that adds, defaults to a codespaces theme.
# See https://github.com/ohmyzsh/ohmyzsh/blob/master/tools/install.sh for official script.
oh_my_install_dir="${user_rc_path}/.oh-my-zsh"
if [ ! -d "${oh_my_install_dir}" ] && [ "${INSTALL_OH_MYS}" = "true" ]; then
template_path="${oh_my_install_dir}/templates/zshrc.zsh-template"
user_rc_file="${user_rc_path}/.zshrc"
umask g-w,o-w
mkdir -p ${oh_my_install_dir}
git clone --depth=1 \
-c core.eol=lf \
-c core.autocrlf=false \
-c fsck.zeroPaddedFilemode=ignore \
-c fetch.fsck.zeroPaddedFilemode=ignore \
-c receive.fsck.zeroPaddedFilemode=ignore \
"https://github.com/ohmyzsh/ohmyzsh" "${oh_my_install_dir}" 2>&1
echo -e "$(cat "${template_path}")\nDISABLE_AUTO_UPDATE=true\nDISABLE_UPDATE_PROMPT=true" > ${user_rc_file}
sed -i -e 's/ZSH_THEME=.*/ZSH_THEME="codespaces"/g' ${user_rc_file}
mkdir -p ${oh_my_install_dir}/custom/themes
echo "${codespaces_zsh}" > "${oh_my_install_dir}/custom/themes/codespaces.zsh-theme"
# Shrink git while still enabling updates
cd "${oh_my_install_dir}"
git repack -a -d -f --depth=1 --window=1
# Copy to non-root user if one is specified
if [ "${USERNAME}" != "root" ]; then
cp -rf "${user_rc_file}" "${oh_my_install_dir}" /root
chown -R ${USERNAME}:${USERNAME} "${user_rc_path}"
fi
fi
fi
# Persist image metadata info, script if meta.env found in same directory
meta_info_script="$(cat << 'EOF'
#!/bin/sh
. /usr/local/etc/vscode-dev-containers/meta.env
# Minimal output
if [ "$1" = "version" ] || [ "$1" = "image-version" ]; then
echo "${VERSION}"
exit 0
elif [ "$1" = "release" ]; then
echo "${GIT_REPOSITORY_RELEASE}"
exit 0
elif [ "$1" = "content" ] || [ "$1" = "content-url" ] || [ "$1" = "contents" ] || [ "$1" = "contents-url" ]; then
echo "${CONTENTS_URL}"
exit 0
fi
#Full output
echo
echo "Development container image information"
echo
if [ ! -z "${VERSION}" ]; then echo "- Image version: ${VERSION}"; fi
if [ ! -z "${DEFINITION_ID}" ]; then echo "- Definition ID: ${DEFINITION_ID}"; fi
if [ ! -z "${VARIANT}" ]; then echo "- Variant: ${VARIANT}"; fi
if [ ! -z "${GIT_REPOSITORY}" ]; then echo "- Source code repository: ${GIT_REPOSITORY}"; fi
if [ ! -z "${GIT_REPOSITORY_RELEASE}" ]; then echo "- Source code release/branch: ${GIT_REPOSITORY_RELEASE}"; fi
if [ ! -z "${BUILD_TIMESTAMP}" ]; then echo "- Timestamp: ${BUILD_TIMESTAMP}"; fi
if [ ! -z "${CONTENTS_URL}" ]; then echo && echo "More info: ${CONTENTS_URL}"; fi
echo
EOF
)"
if [ -f "${SCRIPT_DIR}/meta.env" ]; then
mkdir -p /usr/local/etc/vscode-dev-containers/
cp -f "${SCRIPT_DIR}/meta.env" /usr/local/etc/vscode-dev-containers/meta.env
echo "${meta_info_script}" > /usr/local/bin/devcontainer-info
chmod +x /usr/local/bin/devcontainer-info
fi
# Write marker file
mkdir -p "$(dirname "${MARKER_FILE}")"
echo -e "\
PACKAGES_ALREADY_INSTALLED=${PACKAGES_ALREADY_INSTALLED}\n\
LOCALE_ALREADY_SET=${LOCALE_ALREADY_SET}\n\
EXISTING_NON_ROOT_USER=${EXISTING_NON_ROOT_USER}\n\
RC_SNIPPET_ALREADY_ADDED=${RC_SNIPPET_ALREADY_ADDED}\n\
ZSH_ALREADY_INSTALLED=${ZSH_ALREADY_INSTALLED}" > "${MARKER_FILE}"
echo "Done!"
@@ -1,224 +0,0 @@
#!/usr/bin/env bash
#-------------------------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
#-------------------------------------------------------------------------------------------------------------
#
# Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/docker.md
# Maintainer: The VS Code and Codespaces Teams
#
# Syntax: ./docker-debian.sh [enable non-root docker socket access flag] [source socket] [target socket] [non-root user] [use moby]
ENABLE_NONROOT_DOCKER=${1:-"true"}
SOURCE_SOCKET=${2:-"/var/run/docker-host.sock"}
TARGET_SOCKET=${3:-"/var/run/docker.sock"}
USERNAME=${4:-"automatic"}
USE_MOBY=${5:-"true"}
MICROSOFT_GPG_KEYS_URI="https://packages.microsoft.com/keys/microsoft.asc"
set -e
if [ "$(id -u)" -ne 0 ]; then
echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
exit 1
fi
# Determine the appropriate non-root user
if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then
USERNAME=""
POSSIBLE_USERS=("vscode" "node" "codespace" "$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)")
for CURRENT_USER in ${POSSIBLE_USERS[@]}; do
if id -u ${CURRENT_USER} > /dev/null 2>&1; then
USERNAME=${CURRENT_USER}
break
fi
done
if [ "${USERNAME}" = "" ]; then
USERNAME=root
fi
elif [ "${USERNAME}" = "none" ] || ! id -u ${USERNAME} > /dev/null 2>&1; then
USERNAME=root
fi
# Get central common setting
get_common_setting() {
if [ "${common_settings_file_loaded}" != "true" ]; then
curl -sfL "https://aka.ms/vscode-dev-containers/script-library/settings.env" 2>/dev/null -o /tmp/vsdc-settings.env || echo "Could not download settings file. Skipping."
common_settings_file_loaded=true
fi
if [ -f "/tmp/vsdc-settings.env" ]; then
local multi_line=""
if [ "$2" = "true" ]; then multi_line="-z"; fi
local result="$(grep ${multi_line} -oP "$1=\"?\K[^\"]+" /tmp/vsdc-settings.env | tr -d '\0')"
if [ ! -z "${result}" ]; then declare -g $1="${result}"; fi
fi
echo "$1=${!1}"
}
# Function to run apt-get if needed
apt_get_update_if_needed()
{
if [ ! -d "/var/lib/apt/lists" ] || [ "$(ls /var/lib/apt/lists/ | wc -l)" = "0" ]; then
echo "Running apt-get update..."
apt-get update
else
echo "Skipping apt-get update."
fi
}
# Checks if packages are installed and installs them if not
check_packages() {
if ! dpkg -s "$@" > /dev/null 2>&1; then
apt_get_update_if_needed
apt-get -y install --no-install-recommends "$@"
fi
}
# Ensure apt is in non-interactive to avoid prompts
export DEBIAN_FRONTEND=noninteractive
# Install dependencies
check_packages apt-transport-https curl ca-certificates gnupg2
# Install Docker / Moby CLI if not already installed
if type docker > /dev/null 2>&1; then
echo "Docker / Moby CLI already installed."
else
# Source /etc/os-release to get OS info
. /etc/os-release
if [ "${USE_MOBY}" = "true" ]; then
# Import key safely (new 'signed-by' method rather than deprecated apt-key approach) and install
get_common_setting MICROSOFT_GPG_KEYS_URI
curl -sSL ${MICROSOFT_GPG_KEYS_URI} | gpg --dearmor > /usr/share/keyrings/microsoft-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/microsoft-archive-keyring.gpg] https://packages.microsoft.com/repos/microsoft-${ID}-${VERSION_CODENAME}-prod ${VERSION_CODENAME} main" > /etc/apt/sources.list.d/microsoft.list
apt-get update
apt-get -y install --no-install-recommends moby-cli moby-buildx moby-compose
else
# Import key safely (new 'signed-by' method rather than deprecated apt-key approach) and install
curl -fsSL https://download.docker.com/linux/${ID}/gpg | gpg --dearmor > /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/${ID} ${VERSION_CODENAME} stable" > /etc/apt/sources.list.d/docker.list
apt-get update
apt-get -y install --no-install-recommends docker-ce-cli
fi
fi
# Install Docker Compose if not already installed and is on a supported architecture
if type docker-compose > /dev/null 2>&1; then
echo "Docker Compose already installed."
else
TARGET_COMPOSE_ARCH="$(uname -m)"
if [ "${TARGET_COMPOSE_ARCH}" = "amd64" ]; then
TARGET_COMPOSE_ARCH="x86_64"
fi
if [ "${TARGET_COMPOSE_ARCH}" != "x86_64" ]; then
# Use pip to get a version that runns on this architecture
if ! dpkg -s python3-minimal python3-pip libffi-dev python3-venv pipx > /dev/null 2>&1; then
apt_get_update_if_needed
apt-get -y install python3-minimal python3-pip libffi-dev python3-venv pipx
fi
export PIPX_HOME=/usr/local/pipx
mkdir -p ${PIPX_HOME}
export PIPX_BIN_DIR=/usr/local/bin
export PIP_CACHE_DIR=/tmp/pip-tmp/cache
pipx install --system-site-packages --pip-args '--no-cache-dir --force-reinstall' docker-compose
rm -rf /tmp/pip-tmp
else
LATEST_COMPOSE_VERSION=$(basename "$(curl -fsSL -o /dev/null -w "%{url_effective}" https://github.com/docker/compose/releases/latest)")
curl -fsSL "https://github.com/docker/compose/releases/download/${LATEST_COMPOSE_VERSION}/docker-compose-$(uname -s)-${TARGET_COMPOSE_ARCH}" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
fi
fi
# If init file already exists, exit
if [ -f "/usr/local/share/docker-init.sh" ]; then
exit 0
fi
# By default, make the source and target sockets the same
if [ "${SOURCE_SOCKET}" != "${TARGET_SOCKET}" ]; then
touch "${SOURCE_SOCKET}"
ln -s "${SOURCE_SOCKET}" "${TARGET_SOCKET}"
fi
# Add a stub if not adding non-root user access, user is root
if [ "${ENABLE_NONROOT_DOCKER}" = "false" ] || [ "${USERNAME}" = "root" ]; then
echo '/usr/bin/env bash -c "\$@"' > /usr/local/share/docker-init.sh
chmod +x /usr/local/share/docker-init.sh
exit 0
fi
# If enabling non-root access and specified user is found, setup socat and add script
chown -h "${USERNAME}":root "${TARGET_SOCKET}"
if ! dpkg -s socat > /dev/null 2>&1; then
apt_get_update_if_needed
apt-get -y install socat
fi
tee /usr/local/share/docker-init.sh > /dev/null \
<< EOF
#!/usr/bin/env bash
#-------------------------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
#-------------------------------------------------------------------------------------------------------------
set -e
SOCAT_PATH_BASE=/tmp/vscr-docker-from-docker
SOCAT_LOG=\${SOCAT_PATH_BASE}.log
SOCAT_PID=\${SOCAT_PATH_BASE}.pid
# Wrapper function to only use sudo if not already root
sudoIf()
{
if [ "\$(id -u)" -ne 0 ]; then
sudo "\$@"
else
"\$@"
fi
}
# Log messages
log()
{
echo -e "[\$(date)] \$@" | sudoIf tee -a \${SOCAT_LOG} > /dev/null
}
echo -e "\n** \$(date) **" | sudoIf tee -a \${SOCAT_LOG} > /dev/null
log "Ensuring ${USERNAME} has access to ${SOURCE_SOCKET} via ${TARGET_SOCKET}"
# If enabled, try to add a docker group with the right GID. If the group is root,
# fall back on using socat to forward the docker socket to another unix socket so
# that we can set permissions on it without affecting the host.
if [ "${ENABLE_NONROOT_DOCKER}" = "true" ] && [ "${SOURCE_SOCKET}" != "${TARGET_SOCKET}" ] && [ "${USERNAME}" != "root" ] && [ "${USERNAME}" != "0" ]; then
SOCKET_GID=\$(stat -c '%g' ${SOURCE_SOCKET})
if [ "\${SOCKET_GID}" != "0" ]; then
log "Adding user to group with GID \${SOCKET_GID}."
if [ "\$(cat /etc/group | grep :\${SOCKET_GID}:)" = "" ]; then
sudoIf groupadd --gid \${SOCKET_GID} docker-host
fi
# Add user to group if not already in it
if [ "\$(id ${USERNAME} | grep -E "groups.*(=|,)\${SOCKET_GID}\(")" = "" ]; then
sudoIf usermod -aG \${SOCKET_GID} ${USERNAME}
fi
else
# Enable proxy if not already running
if [ ! -f "\${SOCAT_PID}" ] || ! ps -p \$(cat \${SOCAT_PID}) > /dev/null; then
log "Enabling socket proxy."
log "Proxying ${SOURCE_SOCKET} to ${TARGET_SOCKET} for vscode"
sudoIf rm -rf ${TARGET_SOCKET}
(sudoIf socat UNIX-LISTEN:${TARGET_SOCKET},fork,mode=660,user=${USERNAME} UNIX-CONNECT:${SOURCE_SOCKET} 2>&1 | sudoIf tee -a \${SOCAT_LOG} > /dev/null & echo "\$!" | sudoIf tee \${SOCAT_PID} > /dev/null)
else
log "Socket proxy already running."
fi
fi
log "Success"
fi
# Execute whatever commands were passed in (if any). This allows us
# to set this script to ENTRYPOINT while still executing the default CMD.
set +e
exec "\$@"
EOF
chmod +x /usr/local/share/docker-init.sh
chown ${USERNAME}:root /usr/local/share/docker-init.sh
echo "Done!"
@@ -1,237 +0,0 @@
#!/usr/bin/env bash
#-------------------------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
#-------------------------------------------------------------------------------------------------------------
#
# Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/docker-in-docker.md
# Maintainer: The VS Code and Codespaces Teams
#
# Syntax: ./docker-in-docker-debian.sh [enable non-root docker access flag] [non-root user] [use moby]
ENABLE_NONROOT_DOCKER=${1:-"true"}
USERNAME=${2:-"automatic"}
USE_MOBY=${3:-"true"}
MICROSOFT_GPG_KEYS_URI="https://packages.microsoft.com/keys/microsoft.asc"
set -e
if [ "$(id -u)" -ne 0 ]; then
echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
exit 1
fi
# Determine the appropriate non-root user
if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then
USERNAME=""
POSSIBLE_USERS=("vscode" "node" "codespace" "$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)")
for CURRENT_USER in ${POSSIBLE_USERS[@]}; do
if id -u ${CURRENT_USER} > /dev/null 2>&1; then
USERNAME=${CURRENT_USER}
break
fi
done
if [ "${USERNAME}" = "" ]; then
USERNAME=root
fi
elif [ "${USERNAME}" = "none" ] || ! id -u ${USERNAME} > /dev/null 2>&1; then
USERNAME=root
fi
# Get central common setting
get_common_setting() {
if [ "${common_settings_file_loaded}" != "true" ]; then
curl -sfL "https://aka.ms/vscode-dev-containers/script-library/settings.env" 2>/dev/null -o /tmp/vsdc-settings.env || echo "Could not download settings file. Skipping."
common_settings_file_loaded=true
fi
if [ -f "/tmp/vsdc-settings.env" ]; then
local multi_line=""
if [ "$2" = "true" ]; then multi_line="-z"; fi
local result="$(grep ${multi_line} -oP "$1=\"?\K[^\"]+" /tmp/vsdc-settings.env | tr -d '\0')"
if [ ! -z "${result}" ]; then declare -g $1="${result}"; fi
fi
echo "$1=${!1}"
}
# Function to run apt-get if needed
apt_get_update_if_needed()
{
if [ ! -d "/var/lib/apt/lists" ] || [ "$(ls /var/lib/apt/lists/ | wc -l)" = "0" ]; then
echo "Running apt-get update..."
apt-get update
else
echo "Skipping apt-get update."
fi
}
# Checks if packages are installed and installs them if not
check_packages() {
if ! dpkg -s "$@" > /dev/null 2>&1; then
apt_get_update_if_needed
apt-get -y install --no-install-recommends "$@"
fi
}
# Ensure apt is in non-interactive to avoid prompts
export DEBIAN_FRONTEND=noninteractive
# Install dependencies
check_packages apt-transport-https curl ca-certificates lxc pigz iptables gnupg2
# Swap to legacy iptables for compatibility
if type iptables-legacy > /dev/null 2>&1; then
update-alternatives --set iptables /usr/sbin/iptables-legacy
update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
fi
# Install Docker / Moby CLI if not already installed
if type docker > /dev/null 2>&1 && type dockerd > /dev/null 2>&1; then
echo "Docker / Moby CLI and Engine already installed."
else
# Source /etc/os-release to get OS info
. /etc/os-release
if [ "${USE_MOBY}" = "true" ]; then
# Import key safely (new 'signed-by' method rather than deprecated apt-key approach) and install
get_common_setting MICROSOFT_GPG_KEYS_URI
curl -sSL ${MICROSOFT_GPG_KEYS_URI} | gpg --dearmor > /usr/share/keyrings/microsoft-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/microsoft-archive-keyring.gpg] https://packages.microsoft.com/repos/microsoft-${ID}-${VERSION_CODENAME}-prod ${VERSION_CODENAME} main" > /etc/apt/sources.list.d/microsoft.list
apt-get update
apt-get -y install --no-install-recommends moby-cli moby-buildx moby-compose moby-engine
else
# Import key safely (new 'signed-by' method rather than deprecated apt-key approach) and install
curl -fsSL https://download.docker.com/linux/${ID}/gpg | gpg --dearmor > /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/${ID} ${VERSION_CODENAME} stable" > /etc/apt/sources.list.d/docker.list
apt-get update
apt-get -y install --no-install-recommends docker-ce-cli docker-ce
fi
fi
echo "Finished installing docker / moby"
# Install Docker Compose if not already installed and is on a supported architecture
if type docker-compose > /dev/null 2>&1; then
echo "Docker Compose already installed."
else
TARGET_COMPOSE_ARCH="$(uname -m)"
if [ "${TARGET_COMPOSE_ARCH}" = "amd64" ]; then
TARGET_COMPOSE_ARCH="x86_64"
fi
if [ "${TARGET_COMPOSE_ARCH}" != "x86_64" ]; then
# Use pip to get a version that runns on this architecture
if ! dpkg -s python3-minimal python3-pip libffi-dev python3-venv > /dev/null 2>&1; then
apt_get_update_if_needed
apt-get -y install python3-minimal python3-pip libffi-dev python3-venv
fi
export PIPX_HOME=/usr/local/pipx
mkdir -p ${PIPX_HOME}
export PIPX_BIN_DIR=/usr/local/bin
export PYTHONUSERBASE=/tmp/pip-tmp
export PIP_CACHE_DIR=/tmp/pip-tmp/cache
pipx_bin=pipx
if ! type pipx > /dev/null 2>&1; then
pip3 install --disable-pip-version-check --no-warn-script-location --no-cache-dir --user pipx
pipx_bin=/tmp/pip-tmp/bin/pipx
fi
${pipx_bin} install --system-site-packages --pip-args '--no-cache-dir --force-reinstall' docker-compose
rm -rf /tmp/pip-tmp
else
LATEST_COMPOSE_VERSION=$(basename "$(curl -fsSL -o /dev/null -w "%{url_effective}" https://github.com/docker/compose/releases/latest)")
curl -fsSL "https://github.com/docker/compose/releases/download/${LATEST_COMPOSE_VERSION}/docker-compose-$(uname -s)-${TARGET_COMPOSE_ARCH}" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
fi
fi
# If init file already exists, exit
if [ -f "/usr/local/share/docker-init.sh" ]; then
echo "/usr/local/share/docker-init.sh already exists, so exiting."
exit 0
fi
echo "docker-init doesnt exist..."
# Add user to the docker group
if [ "${ENABLE_NONROOT_DOCKER}" = "true" ]; then
if ! getent group docker > /dev/null 2>&1; then
groupadd docker
fi
usermod -aG docker ${USERNAME}
fi
tee /usr/local/share/docker-init.sh > /dev/null \
<< 'EOF'
#!/usr/bin/env bash
#-------------------------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
#-------------------------------------------------------------------------------------------------------------
sudoIf()
{
if [ "$(id -u)" -ne 0 ]; then
sudo "$@"
else
"$@"
fi
}
# explicitly remove dockerd and containerd PID file to ensure that it can start properly if it was stopped uncleanly
# ie: docker kill <ID>
sudoIf find /run /var/run -iname 'docker*.pid' -delete || :
sudoIf find /run /var/run -iname 'container*.pid' -delete || :
set -e
## Dind wrapper script from docker team
# Maintained: https://github.com/moby/moby/blob/master/hack/dind
export container=docker
if [ -d /sys/kernel/security ] && ! sudoIf mountpoint -q /sys/kernel/security; then
sudoIf mount -t securityfs none /sys/kernel/security || {
echo >&2 'Could not mount /sys/kernel/security.'
echo >&2 'AppArmor detection and --privileged mode might break.'
}
fi
# Mount /tmp (conditionally)
if ! sudoIf mountpoint -q /tmp; then
sudoIf mount -t tmpfs none /tmp
fi
# cgroup v2: enable nesting
if [ -f /sys/fs/cgroup/cgroup.controllers ]; then
# move the init process (PID 1) from the root group to the /init group,
# otherwise writing subtree_control fails with EBUSY.
sudoIf mkdir -p /sys/fs/cgroup/init
sudoIf echo 1 > /sys/fs/cgroup/init/cgroup.procs
# enable controllers
sudoIf sed -e 's/ / +/g' -e 's/^/+/' < /sys/fs/cgroup/cgroup.controllers \
> /sys/fs/cgroup/cgroup.subtree_control
fi
## Dind wrapper over.
# Handle DNS
set +e
cat /etc/resolv.conf | grep -i 'internal.cloudapp.net'
if [ $? -eq 0 ]
then
echo "Setting dockerd Azure DNS."
CUSTOMDNS="--dns 168.63.129.16"
else
echo "Not setting dockerd DNS manually."
CUSTOMDNS=""
fi
set -e
# Start docker/moby engine
( sudoIf dockerd $CUSTOMDNS > /tmp/dockerd.log 2>&1 ) &
set +e
# Execute whatever commands were passed in (if any). This allows us
# to set this script to ENTRYPOINT while still executing the default CMD.
exec "$@"
EOF
chmod +x /usr/local/share/docker-init.sh
chown ${USERNAME}:root /usr/local/share/docker-init.sh
@@ -1,140 +0,0 @@
#!/usr/bin/env bash
#-------------------------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
#-------------------------------------------------------------------------------------------------------------
#
# Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/git-from-src.md
# Maintainer: The VS Code and Codespaces Teams
#
# Syntax: ./git-from-src-debian.sh [version] [use PPA if available]
GIT_VERSION=${1:-"latest"}
USE_PPA_IF_AVAILABLE=${2:-"false"}
GIT_CORE_PPA_ARCHIVE_GPG_KEY=E1DD270288B4E6030699E45FA1715D88E1DF1F24
GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com:80
keyserver hkps://keys.openpgp.org
keyserver hkp://keyserver.pgp.com"
set -e
if [ "$(id -u)" -ne 0 ]; then
echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
exit 1
fi
# Get central common setting
get_common_setting() {
if [ "${common_settings_file_loaded}" != "true" ]; then
curl -sfL "https://aka.ms/vscode-dev-containers/script-library/settings.env" 2>/dev/null -o /tmp/vsdc-settings.env || echo "Could not download settings file. Skipping."
common_settings_file_loaded=true
fi
if [ -f "/tmp/vsdc-settings.env" ]; then
local multi_line=""
if [ "$2" = "true" ]; then multi_line="-z"; fi
local result="$(grep ${multi_line} -oP "$1=\"?\K[^\"]+" /tmp/vsdc-settings.env | tr -d '\0')"
if [ ! -z "${result}" ]; then declare -g $1="${result}"; fi
fi
echo "$1=${!1}"
}
# Import the specified key in a variable name passed in as
receive_gpg_keys() {
get_common_setting $1
local keys=${!1}
get_common_setting GPG_KEY_SERVERS true
local keyring_args=""
if [ ! -z "$2" ]; then
mkdir -p "$(dirname \"$2\")"
keyring_args="--no-default-keyring --keyring $2"
fi
# Use a temporary locaiton for gpg keys to avoid polluting image
export GNUPGHOME="/tmp/tmp-gnupg"
mkdir -p ${GNUPGHOME}
chmod 700 ${GNUPGHOME}
echo -e "disable-ipv6\n${GPG_KEY_SERVERS}" > ${GNUPGHOME}/dirmngr.conf
# GPG key download sometimes fails for some reason and retrying fixes it.
local retry_count=0
local gpg_ok="false"
set +e
until [ "${gpg_ok}" = "true" ] || [ "${retry_count}" -eq "5" ];
do
echo "(*) Downloading GPG key..."
( echo "${keys}" | xargs -n 1 gpg -q ${keyring_args} --recv-keys) 2>&1 && gpg_ok="true"
if [ "${gpg_ok}" != "true" ]; then
echo "(*) Failed getting key, retring in 10s..."
(( retry_count++ ))
sleep 10s
fi
done
set -e
if [ "${gpg_ok}" = "false" ]; then
echo "(!) Failed to install rvm."
exit 1
fi
}
# Function to run apt-get if needed
apt_get_update_if_needed()
{
if [ ! -d "/var/lib/apt/lists" ] || [ "$(ls /var/lib/apt/lists/ | wc -l)" = "0" ]; then
echo "Running apt-get update..."
apt-get update
else
echo "Skipping apt-get update."
fi
}
# Checks if packages are installed and installs them if not
check_packages() {
if ! dpkg -s "$@" > /dev/null 2>&1; then
apt_get_update_if_needed
apt-get -y install --no-install-recommends "$@"
fi
}
export DEBIAN_FRONTEND=noninteractive
# Source /etc/os-release to get OS info
. /etc/os-release
# If ubuntu, PPAs allowed, and latest - install from there
if ([ "${GIT_VERSION}" = "latest" ] || [ "${GIT_VERSION}" = "lts" ] || [ "${GIT_VERSION}" = "current" ]) && [ "${ID}" = "ubuntu" ] && [ "${USE_PPA_IF_AVAILABLE}" = "true" ]; then
echo "Using PPA to install latest git..."
check_packages apt-transport-https curl ca-certificates gnupg2
receive_gpg_keys GIT_CORE_PPA_ARCHIVE_GPG_KEY /usr/share/keyrings/gitcoreppa-archive-keyring.gpg
echo -e "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/gitcoreppa-archive-keyring.gpg] http://ppa.launchpad.net/git-core/ppa/ubuntu ${VERSION_CODENAME} main\ndeb-src [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/gitcoreppa-archive-keyring.gpg] http://ppa.launchpad.net/git-core/ppa/ubuntu ${VERSION_CODENAME} main" > /etc/apt/sources.list.d/git-core-ppa.list
apt-get update
apt-get -y install --no-install-recommends git
rm -rf "/tmp/tmp-gnupg"
exit 0
fi
# Install required packages to build if missing
check_packages build-essential curl ca-certificates tar gettext libssl-dev zlib1g-dev libcurl?-openssl-dev libexpat1-dev
# Partial version matching
if [ "$(echo "${GIT_VERSION}" | grep -o '\.' | wc -l)" != "2" ]; then
requested_version="${GIT_VERSION}"
version_list="$(curl -sSL -H "Accept: application/vnd.github.v3+json" "https://api.github.com/repos/git/git/tags" | grep -oP '"name":\s*"v\K[0-9]+\.[0-9]+\.[0-9]+"' | tr -d '"' | sort -rV )"
if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "lts" ] || [ "${requested_version}" = "current" ]; then
GIT_VERSION="$(echo "${version_list}" | head -n 1)"
else
set +e
GIT_VERSION="$(echo "${version_list}" | grep -E -m 1 "^${requested_version//./\\.}([\\.\\s]|$)")"
set -e
fi
if [ -z "${GIT_VERSION}" ] || ! echo "${version_list}" | grep "^${GIT_VERSION//./\\.}$" > /dev/null 2>&1; then
echo "Invalid git version: ${requested_version}" >&2
exit 1
fi
fi
echo "Downloading source for ${GIT_VERSION}..."
curl -sL https://github.com/git/git/archive/v${GIT_VERSION}.tar.gz | tar -xzC /tmp 2>&1
echo "Building..."
cd /tmp/git-${GIT_VERSION}
make -s prefix=/usr/local all && make -s prefix=/usr/local install 2>&1
rm -rf /tmp/git-${GIT_VERSION}
echo "Done!"
@@ -1,188 +0,0 @@
#!/usr/bin/env bash
#-------------------------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
#-------------------------------------------------------------------------------------------------------------
#
# Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/github.md
# Maintainer: The VS Code and Codespaces Teams
#
# Syntax: ./github-debian.sh [version]
CLI_VERSION=${1:-"latest"}
GITHUB_CLI_ARCHIVE_GPG_KEY=C99B11DEB97541F0
GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com:80
keyserver hkps://keys.openpgp.org
keyserver hkp://keyserver.pgp.com"
set -e
if [ "$(id -u)" -ne 0 ]; then
echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
exit 1
fi
# Get central common setting
get_common_setting() {
if [ "${common_settings_file_loaded}" != "true" ]; then
curl -sfL "https://aka.ms/vscode-dev-containers/script-library/settings.env" 2>/dev/null -o /tmp/vsdc-settings.env || echo "Could not download settings file. Skipping."
common_settings_file_loaded=true
fi
if [ -f "/tmp/vsdc-settings.env" ]; then
local multi_line=""
if [ "$2" = "true" ]; then multi_line="-z"; fi
local result="$(grep ${multi_line} -oP "$1=\"?\K[^\"]+" /tmp/vsdc-settings.env | tr -d '\0')"
if [ ! -z "${result}" ]; then declare -g $1="${result}"; fi
fi
echo "$1=${!1}"
}
# Import the specified key in a variable name passed in as
receive_gpg_keys() {
get_common_setting $1
local keys=${!1}
get_common_setting GPG_KEY_SERVERS true
# Use a temporary locaiton for gpg keys to avoid polluting image
export GNUPGHOME="/tmp/tmp-gnupg"
mkdir -p ${GNUPGHOME}
chmod 700 ${GNUPGHOME}
echo -e "disable-ipv6\n${GPG_KEY_SERVERS}" > ${GNUPGHOME}/dirmngr.conf
# GPG key download sometimes fails for some reason and retrying fixes it.
local retry_count=0
local gpg_ok="false"
set +e
until [ "${gpg_ok}" = "true" ] || [ "${retry_count}" -eq "5" ];
do
echo "(*) Downloading GPG key..."
( echo "${keys}" | xargs -n 1 gpg --recv-keys) 2>&1 && gpg_ok="true"
if [ "${gpg_ok}" != "true" ]; then
echo "(*) Failed getting key, retring in 10s..."
(( retry_count++ ))
sleep 10s
fi
done
set -e
if [ "${gpg_ok}" = "false" ]; then
echo "(!) Failed to install rvm."
exit 1
fi
}
# Figure out correct version of a three part version number is not passed
find_version_from_git_tags() {
local variable_name=$1
local requested_version=${!variable_name}
if [ "${requested_version}" = "none" ]; then return; fi
local repository=$2
local prefix=${3:-"tags/v"}
local separator=${4:-"."}
local last_part_optional=${5:-"false"}
if [ "$(echo "${requested_version}" | grep -o "." | wc -l)" != "2" ]; then
local escaped_separator=${separator//./\\.}
local last_part
if [ "${last_part_optional}" = "true" ]; then
last_part="(${escaped_separator}[0-9]+)?"
else
last_part="${escaped_separator}[0-9]+"
fi
local regex="${prefix}\\K[0-9]+${escaped_separator}[0-9]+${last_part}$"
local version_list="$(git ls-remote --tags ${repository} | grep -oP "${regex}" | tr -d ' ' | tr "${separator}" "." | sort -rV)"
if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ] || [ "${requested_version}" = "lts" ]; then
declare -g ${variable_name}="$(echo "${version_list}" | head -n 1)"
else
set +e
declare -g ${variable_name}="$(echo "${version_list}" | grep -E -m 1 "^${requested_version//./\\.}([\\.\\s]|$)")"
set -e
fi
fi
if [ -z "${!variable_name}" ] || ! echo "${version_list}" | grep "^${!variable_name//./\\.}$" > /dev/null 2>&1; then
echo -e "Invalid ${variable_name} value: ${requested_version}\nValid values:\n${version_list}" >&2
exit 1
fi
echo "${variable_name}=${!variable_name}"
}
# Import the specified key in a variable name passed in as
receive_gpg_keys() {
get_common_setting $1
local keys=${!1}
get_common_setting GPG_KEY_SERVERS true
local keyring_args=""
if [ ! -z "$2" ]; then
keyring_args="--no-default-keyring --keyring $2"
fi
# Use a temporary locaiton for gpg keys to avoid polluting image
export GNUPGHOME="/tmp/tmp-gnupg"
mkdir -p ${GNUPGHOME}
chmod 700 ${GNUPGHOME}
echo -e "disable-ipv6\n${GPG_KEY_SERVERS}" > ${GNUPGHOME}/dirmngr.conf
# GPG key download sometimes fails for some reason and retrying fixes it.
local retry_count=0
local gpg_ok="false"
set +e
until [ "${gpg_ok}" = "true" ] || [ "${retry_count}" -eq "5" ];
do
echo "(*) Downloading GPG key..."
( echo "${keys}" | xargs -n 1 gpg -q ${keyring_args} --recv-keys) 2>&1 && gpg_ok="true"
if [ "${gpg_ok}" != "true" ]; then
echo "(*) Failed getting key, retring in 10s..."
(( retry_count++ ))
sleep 10s
fi
done
set -e
if [ "${gpg_ok}" = "false" ]; then
echo "(!) Failed to install rvm."
exit 1
fi
}
# Function to run apt-get if needed
apt_get_update_if_needed()
{
if [ ! -d "/var/lib/apt/lists" ] || [ "$(ls /var/lib/apt/lists/ | wc -l)" = "0" ]; then
echo "Running apt-get update..."
apt-get update
else
echo "Skipping apt-get update."
fi
}
# Checks if packages are installed and installs them if not
check_packages() {
if ! dpkg -s "$@" > /dev/null 2>&1; then
apt_get_update_if_needed
apt-get -y install --no-install-recommends "$@"
fi
}
export DEBIAN_FRONTEND=noninteractive
# Install curl, apt-transport-https, curl, gpg, or dirmngr, git if missing
check_packages curl ca-certificates apt-transport-https dirmngr gnupg2
if ! type git > /dev/null 2>&1; then
apt_get_update_if_needed
apt-get -y install --no-install-recommends git
fi
# Soft version matching
if [ "${CLI_VERSION}" != "latest" ] && [ "${CLI_VERSION}" != "lts" ] && [ "${CLI_VERSION}" != "stable" ]; then
find_version_from_git_tags CLI_VERSION "https://github.com/cli/cli"
version_suffix="=${CLI_VERSION}"
else
version_suffix=""
fi
# Install the GitHub CLI
echo "Downloading github CLI..."
# Import key safely (new method rather than deprecated apt-key approach) and install
. /etc/os-release
receive_gpg_keys GITHUB_CLI_ARCHIVE_GPG_KEY /usr/share/keyrings/githubcli-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages ${VERSION_CODENAME} main" > /etc/apt/sources.list.d/github-cli.list
apt-get update
apt-get -y install "gh${version_suffix}"
rm -rf "/tmp/gh/gnupg"
echo "Done!"
-201
View File
@@ -1,201 +0,0 @@
#!/usr/bin/env bash
#-------------------------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
#-------------------------------------------------------------------------------------------------------------
#
# Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/go.md
# Maintainer: The VS Code and Codespaces Teams
#
# Syntax: ./go-debian.sh [Go version] [GOROOT] [GOPATH] [non-root user] [Add GOPATH, GOROOT to rc files flag] [Install tools flag]
TARGET_GO_VERSION=${1:-"latest"}
TARGET_GOROOT=${2:-"/usr/local/go"}
TARGET_GOPATH=${3:-"/go"}
USERNAME=${4:-"automatic"}
UPDATE_RC=${5:-"true"}
INSTALL_GO_TOOLS=${6:-"true"}
set -e
if [ "$(id -u)" -ne 0 ]; then
echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
exit 1
fi
# Ensure that login shells get the correct path if the user updated the PATH using ENV.
rm -f /etc/profile.d/00-restore-env.sh
echo "export PATH=${PATH//$(sh -lc 'echo $PATH')/\$PATH}" > /etc/profile.d/00-restore-env.sh
chmod +x /etc/profile.d/00-restore-env.sh
# Determine the appropriate non-root user
if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then
USERNAME=""
POSSIBLE_USERS=("vscode" "node" "codespace" "$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)")
for CURRENT_USER in ${POSSIBLE_USERS[@]}; do
if id -u ${CURRENT_USER} > /dev/null 2>&1; then
USERNAME=${CURRENT_USER}
break
fi
done
if [ "${USERNAME}" = "" ]; then
USERNAME=root
fi
elif [ "${USERNAME}" = "none" ] || ! id -u ${USERNAME} > /dev/null 2>&1; then
USERNAME=root
fi
updaterc() {
if [ "${UPDATE_RC}" = "true" ]; then
echo "Updating /etc/bash.bashrc and /etc/zsh/zshrc..."
echo -e "$1" >> /etc/bash.bashrc
if [ -f "/etc/zsh/zshrc" ]; then
echo -e "$1" >> /etc/zsh/zshrc
fi
fi
}
# Figure out correct version of a three part version number is not passed
find_version_from_git_tags() {
local variable_name=$1
local requested_version=${!variable_name}
if [ "${requested_version}" = "none" ]; then return; fi
local repository=$2
local prefix=${3:-"tags/v"}
local separator=${4:-"."}
local last_part_optional=${5:-"false"}
if [ "$(echo "${requested_version}" | grep -o "." | wc -l)" != "2" ]; then
local escaped_separator=${separator//./\\.}
local last_part
if [ "${last_part_optional}" = "true" ]; then
last_part="(${escaped_separator}[0-9]+)?"
else
last_part="${escaped_separator}[0-9]+"
fi
local regex="${prefix}\\K[0-9]+${escaped_separator}[0-9]+${last_part}$"
local version_list="$(git ls-remote --tags ${repository} | grep -oP "${regex}" | tr -d ' ' | tr "${separator}" "." | sort -rV)"
if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ] || [ "${requested_version}" = "lts" ]; then
declare -g ${variable_name}="$(echo "${version_list}" | head -n 1)"
else
set +e
declare -g ${variable_name}="$(echo "${version_list}" | grep -E -m 1 "^${requested_version//./\\.}([\\.\\s]|$)")"
set -e
fi
fi
if [ -z "${!variable_name}" ] || ! echo "${version_list}" | grep "^${!variable_name//./\\.}$" > /dev/null 2>&1; then
echo -e "Invalid ${variable_name} value: ${requested_version}\nValid values:\n${version_list}" >&2
exit 1
fi
echo "${variable_name}=${!variable_name}"
}
# Function to run apt-get if needed
apt_get_update_if_needed()
{
if [ ! -d "/var/lib/apt/lists" ] || [ "$(ls /var/lib/apt/lists/ | wc -l)" = "0" ]; then
echo "Running apt-get update..."
apt-get update
else
echo "Skipping apt-get update."
fi
}
# Checks if packages are installed and installs them if not
check_packages() {
if ! dpkg -s "$@" > /dev/null 2>&1; then
apt_get_update_if_needed
apt-get -y install --no-install-recommends "$@"
fi
}
export DEBIAN_FRONTEND=noninteractive
# Install curl, tar, git, other dependencies if missing
check_packages curl ca-certificates tar g++ gcc libc6-dev make pkg-config
if ! type git > /dev/null 2>&1; then
apt_get_update_if_needed
apt-get -y install --no-install-recommends git
fi
# Get closest match for version number specified
find_version_from_git_tags TARGET_GO_VERSION "https://go.googlesource.com/go" "tags/go" "." "true"
architecture="$(uname -m)"
case $architecture in
x86_64) architecture="amd64";;
aarch64 | armv8*) architecture="arm64";;
aarch32 | armv7* | armvhf*) architecture="armv6l";;
i?86) architecture="386";;
*) echo "(!) Architecture $architecture unsupported"; exit 1 ;;
esac
# Install Go
GO_INSTALL_SCRIPT="$(cat <<EOF
set -e
echo "Downloading Go ${TARGET_GO_VERSION}..."
curl -sSL -o /tmp/go.tar.gz "https://golang.org/dl/go${TARGET_GO_VERSION}.linux-${architecture}.tar.gz"
echo "Extracting Go ${TARGET_GO_VERSION}..."
tar -xzf /tmp/go.tar.gz -C "${TARGET_GOROOT}" --strip-components=1
rm -f /tmp/go.tar.gz
EOF
)"
if [ "${TARGET_GO_VERSION}" != "none" ] && ! type go > /dev/null 2>&1; then
mkdir -p "${TARGET_GOROOT}" "${TARGET_GOPATH}"
chown -R ${USERNAME} "${TARGET_GOROOT}" "${TARGET_GOPATH}"
su ${USERNAME} -c "${GO_INSTALL_SCRIPT}"
else
echo "Go already installed. Skipping."
fi
# Install Go tools that are isImportant && !replacedByGopls based on
# https://github.com/golang/vscode-go/blob/0ff533d408e4eb8ea54ce84d6efa8b2524d62873/src/goToolsInformation.ts
# Exception `dlv-dap` is a copy of github.com/go-delve/delve/cmd/dlv built from the master.
GO_TOOLS="\
golang.org/x/tools/gopls@latest \
honnef.co/go/tools/cmd/staticcheck@latest \
golang.org/x/lint/golint@latest \
github.com/mgechev/revive@latest \
github.com/uudashr/gopkgs/v2/cmd/gopkgs@latest \
github.com/ramya-rao-a/go-outline@latest \
github.com/go-delve/delve/cmd/dlv@latest \
github.com/golangci/golangci-lint/cmd/golangci-lint@latest"
if [ "${INSTALL_GO_TOOLS}" = "true" ]; then
echo "Installing common Go tools..."
export PATH=${TARGET_GOROOT}/bin:${PATH}
mkdir -p /tmp/gotools /usr/local/etc/vscode-dev-containers ${TARGET_GOPATH}/bin
cd /tmp/gotools
export GOPATH=/tmp/gotools
export GOCACHE=/tmp/gotools/cache
# Use go get for versions of go under 1.17
go_install_command=install
if [[ "1.16" > "$(go version | grep -oP 'go\K[0-9]+\.[0-9]+(\.[0-9]+)?')" ]]; then
export GO111MODULE=on
go_install_command=get
echo "Go version < 1.17, using go get."
fi
(echo "${GO_TOOLS}" | xargs -n 1 go ${go_install_command} -v )2>&1 | tee -a /usr/local/etc/vscode-dev-containers/go.log
# Move Go tools into path and clean up
mv /tmp/gotools/bin/* ${TARGET_GOPATH}/bin/
# install dlv-dap (dlv@master)
go ${go_install_command} -v github.com/go-delve/delve/cmd/dlv@master 2>&1 | tee -a /usr/local/etc/vscode-dev-containers/go.log
mv /tmp/gotools/bin/dlv ${TARGET_GOPATH}/bin/dlv-dap
rm -rf /tmp/gotools
chown -R ${USERNAME} "${TARGET_GOPATH}"
fi
# Add GOPATH variable and bin directory into PATH in bashrc/zshrc files (unless disabled)
updaterc "$(cat << EOF
export GOPATH="${TARGET_GOPATH}"
if [[ "\${PATH}" != *"\${GOPATH}/bin"* ]]; then export PATH="\${PATH}:\${GOPATH}/bin"; fi
export GOROOT="${TARGET_GOROOT}"
if [[ "\${PATH}" != *"\${GOROOT}/bin"* ]]; then export PATH="\${PATH}:\${GOROOT}/bin"; fi
EOF
)"
echo "Done!"
-105
View File
@@ -1,105 +0,0 @@
#!/usr/bin/env bash
#
# This is a replicated script.
#
# Syntax: ./k3s-debian.sh [k3s version] [k3s SHA256]
set -e
K3S_VERSION="${1:-"latest"}" # latest is also valid
K3S_SHA256="${2:-"automatic"}"
GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com:80
keyserver hkps://keys.openpgp.org
keyserver hkp://keyserver.pgp.com"
architecture="$(uname -m)"
case $architecture in
x86_64) architecture="amd64";;
aarch64 | armv8*) architecture="arm64";;
aarch32 | armv7* | armvhf*) architecture="armhf";;
*) echo "(!) Architecture $architecture unsupported"; exit 1 ;;
esac
# Figure out correct version of a three part version number is not passed
find_version_from_git_tags() {
local variable_name=$1
local requested_version=${!variable_name}
if [ "${requested_version}" = "none" ]; then return; fi
local repository=$2
local prefix=${3:-"tags/v"}
local separator=${4:-"."}
local last_part_optional=${5:-"false"}
if [ "$(echo "${requested_version}" | grep -o "." | wc -l)" != "2" ]; then
local escaped_separator=${separator//./\\.}
local last_part
if [ "${last_part_optional}" = "true" ]; then
last_part="(${escaped_separator}[0-9ks\+]+)?"
else
last_part="${escaped_separator}[0-9ks\+]+"
fi
local regex="${prefix}\\K[0-9]+${escaped_separator}[0-9]+${last_part}$"
local version_list="$(git ls-remote --tags ${repository} | grep -oP "${regex}" | tr -d ' ' | tr "${separator}" "." | sort -rV)"
echo $version_list
if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ] || [ "${requested_version}" = "lts" ]; then
declare -g ${variable_name}="$(echo "${version_list}" | head -n 1)"
else
set +e
declare -g ${variable_name}="$(echo "${version_list}" | grep -E -m 1 "^${requested_version//./\\.}([\\.\\s+]|$)")"
set -e
fi
fi
if [ -z "${!variable_name}" ] || ! echo "${version_list}" | grep "^${!variable_name//./\\.}$" > /dev/null 2>&1; then
echo -e "Invalid ${variable_name} value: ${requested_version}\nValid values:\n${version_list}" >&2
exit 1
fi
echo "${variable_name}=${!variable_name}"
}
# Install K3s, verify checksum
if [ "${K3S_VERSION}" != "none" ]; then
echo "Downloading k3s..."
urlPrefix=
if [ "${K3S_VERSION}" = "latest" ] || [ "${K3S_VERSION}" = "lts" ] || [ "${K3S_VERSION}" = "current" ] || [ "${K3S_VERSION}" = "stable" ]; then
K3S_VERSION="latest"
urlPrefix="https://github.com/k3s-io/k3s/releases/latest/download"
else
find_version_from_git_tags K3S_VERSION https://github.com/k3s-io/k3s
if [ "${K3S_VERSION::1}" != "v" ]; then
K3S_VERSION="v${K3S_VERSION}"
fi
urlPrefix="https://github.com/k3s-io/k3s/releases/download/${K3S_VERSION}"
fi
# URL encode plus sign
K3S_VERSION="$(echo $K3S_VERSION | sed --expression='s/+/%2B/g')"
# latest is also valid in the download URLs
downloadUrl="${urlPrefix}/k3s${architecture}"
if [ "${architecture}" = "amd64" ]; then
downloadUrl="${urlPrefix}/k3s"
fi
curl -sSL -o /usr/local/bin/k3s "${downloadUrl}"
chmod 0755 /usr/local/bin/k3s
if [ "$K3S_SHA256" = "automatic" ]; then
shaUrl="${urlPrefix}/sha256sum-${architecture}.txt"
if [ "${architecture}" = "armhf" ]; then
shaUrl="${urlPrefix}/sha256sum-arm.txt"
fi
# Manifest contains image hashes, but we only need the binary
K3S_SHA256="$(curl -sSL $shaUrl | grep -P '(^|\s)\Kk3s(?=\s|$)' | cut -d ' ' -f1 )"
fi
echo $K3S_SHA256
([ "${K3S_SHA256}" = "dev-mode" ] || (echo "${K3S_SHA256} */usr/local/bin/k3s" | sha256sum -c -))
if ! type k3s > /dev/null 2>&1; then
echo '(!) k3s installation failed!'
exit 1
fi
fi
echo -e "\nDone!"
@@ -1,218 +0,0 @@
#!/usr/bin/env bash
#-------------------------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
#-------------------------------------------------------------------------------------------------------------
#
# Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/kubectl-helm.md
# Maintainer: The VS Code and Codespaces Teams
#
# Syntax: ./kubectl-helm-debian.sh [kubectl verison] [Helm version] [minikube version] [kubectl SHA256] [Helm SHA256] [minikube SHA256]
set -e
KUBECTL_VERSION="${1:-"latest"}"
HELM_VERSION="${2:-"latest"}"
MINIKUBE_VERSION="${3:-"none"}" # latest is also valid
KUBECTL_SHA256="${4:-"automatic"}"
HELM_SHA256="${5:-"automatic"}"
MINIKUBE_SHA256="${6:-"automatic"}"
HELM_GPG_KEYS_URI="https://raw.githubusercontent.com/helm/helm/main/KEYS"
GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com:80
keyserver hkps://keys.openpgp.org
keyserver hkp://keyserver.pgp.com"
if [ "$(id -u)" -ne 0 ]; then
echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
exit 1
fi
# Get central common setting
get_common_setting() {
if [ "${common_settings_file_loaded}" != "true" ]; then
curl -sfL "https://aka.ms/vscode-dev-containers/script-library/settings.env" 2>/dev/null -o /tmp/vsdc-settings.env || echo "Could not download settings file. Skipping."
common_settings_file_loaded=true
fi
if [ -f "/tmp/vsdc-settings.env" ]; then
local multi_line=""
if [ "$2" = "true" ]; then multi_line="-z"; fi
local result="$(grep ${multi_line} -oP "$1=\"?\K[^\"]+" /tmp/vsdc-settings.env | tr -d '\0')"
if [ ! -z "${result}" ]; then declare -g $1="${result}"; fi
fi
echo "$1=${!1}"
}
# Figure out correct version of a three part version number is not passed
find_version_from_git_tags() {
local variable_name=$1
local requested_version=${!variable_name}
if [ "${requested_version}" = "none" ]; then return; fi
local repository=$2
local prefix=${3:-"tags/v"}
local separator=${4:-"."}
local last_part_optional=${5:-"false"}
if [ "$(echo "${requested_version}" | grep -o "." | wc -l)" != "2" ]; then
local escaped_separator=${separator//./\\.}
local last_part
if [ "${last_part_optional}" = "true" ]; then
last_part="(${escaped_separator}[0-9]+)?"
else
last_part="${escaped_separator}[0-9]+"
fi
local regex="${prefix}\\K[0-9]+${escaped_separator}[0-9]+${last_part}$"
local version_list="$(git ls-remote --tags ${repository} | grep -oP "${regex}" | tr -d ' ' | tr "${separator}" "." | sort -rV)"
if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ] || [ "${requested_version}" = "lts" ]; then
declare -g ${variable_name}="$(echo "${version_list}" | head -n 1)"
else
set +e
declare -g ${variable_name}="$(echo "${version_list}" | grep -E -m 1 "^${requested_version//./\\.}([\\.\\s]|$)")"
set -e
fi
fi
if [ -z "${!variable_name}" ] || ! echo "${version_list}" | grep "^${!variable_name//./\\.}$" > /dev/null 2>&1; then
echo -e "Invalid ${variable_name} value: ${requested_version}\nValid values:\n${version_list}" >&2
exit 1
fi
echo "${variable_name}=${!variable_name}"
}
# Function to run apt-get if needed
apt_get_update_if_needed()
{
if [ ! -d "/var/lib/apt/lists" ] || [ "$(ls /var/lib/apt/lists/ | wc -l)" = "0" ]; then
echo "Running apt-get update..."
apt-get update
else
echo "Skipping apt-get update."
fi
}
# Checks if packages are installed and installs them if not
check_packages() {
if ! dpkg -s "$@" > /dev/null 2>&1; then
apt_get_update_if_needed
apt-get -y install --no-install-recommends "$@"
fi
}
# Ensure apt is in non-interactive to avoid prompts
export DEBIAN_FRONTEND=noninteractive
# Install dependencies
check_packages curl ca-certificates coreutils gnupg2 dirmngr bash-completion
if ! type git > /dev/null 2>&1; then
apt_get_update_if_needed
apt-get -y install --no-install-recommends git
fi
architecture="$(uname -m)"
case $architecture in
x86_64) architecture="amd64";;
aarch64 | armv8*) architecture="arm64";;
aarch32 | armv7* | armvhf*) architecture="arm";;
i?86) architecture="386";;
*) echo "(!) Architecture $architecture unsupported"; exit 1 ;;
esac
# Install the kubectl, verify checksum
echo "Downloading kubectl..."
if [ "${KUBECTL_VERSION}" = "latest" ] || [ "${KUBECTL_VERSION}" = "lts" ] || [ "${KUBECTL_VERSION}" = "current" ] || [ "${KUBECTL_VERSION}" = "stable" ]; then
KUBECTL_VERSION="$(curl -sSL https://dl.k8s.io/release/stable.txt)"
else
find_version_from_git_tags KUBECTL_VERSION https://github.com/kubernetes/kubernetes
fi
if [ "${KUBECTL_VERSION::1}" != 'v' ]; then
KUBECTL_VERSION="v${KUBECTL_VERSION}"
fi
curl -sSL -o /usr/local/bin/kubectl "https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/${architecture}/kubectl"
chmod 0755 /usr/local/bin/kubectl
if [ "$KUBECTL_SHA256" = "automatic" ]; then
KUBECTL_SHA256="$(curl -sSL "https://dl.k8s.io/${KUBECTL_VERSION}/bin/linux/${architecture}/kubectl.sha256")"
fi
([ "${KUBECTL_SHA256}" = "dev-mode" ] || (echo "${KUBECTL_SHA256} */usr/local/bin/kubectl" | sha256sum -c -))
if ! type kubectl > /dev/null 2>&1; then
echo '(!) kubectl installation failed!'
exit 1
fi
# kubectl bash completion
kubectl completion bash > /etc/bash_completion.d/kubectl
# kubectl zsh completion
mkdir -p /home/${USERNAME}/.oh-my-zsh/completions
kubectl completion zsh > /home/${USERNAME}/.oh-my-zsh/completions/_kubectl
# Install Helm, verify signature and checksum
echo "Downloading Helm..."
find_version_from_git_tags HELM_VERSION "https://github.com/helm/helm"
if [ "${HELM_VERSION::1}" != 'v' ]; then
HELM_VERSION="v${HELM_VERSION}"
fi
mkdir -p /tmp/helm
helm_filename="helm-${HELM_VERSION}-linux-${architecture}.tar.gz"
tmp_helm_filename="/tmp/helm/${helm_filename}"
curl -sSL "https://get.helm.sh/${helm_filename}" -o "${tmp_helm_filename}"
curl -sSL "https://github.com/helm/helm/releases/download/${HELM_VERSION}/${helm_filename}.asc" -o "${tmp_helm_filename}.asc"
export GNUPGHOME="/tmp/helm/gnupg"
mkdir -p "${GNUPGHOME}"
chmod 700 ${GNUPGHOME}
get_common_setting HELM_GPG_KEYS_URI
get_common_setting GPG_KEY_SERVERS true
curl -sSL "${HELM_GPG_KEYS_URI}" -o /tmp/helm/KEYS
echo -e "disable-ipv6\n${GPG_KEY_SERVERS}" > ${GNUPGHOME}/dirmngr.conf
gpg -q --import "/tmp/helm/KEYS"
if ! gpg --verify "${tmp_helm_filename}.asc" > ${GNUPGHOME}/verify.log 2>&1; then
echo "Verification failed!"
cat /tmp/helm/gnupg/verify.log
exit 1
fi
if [ "${HELM_SHA256}" = "automatic" ]; then
curl -sSL "https://get.helm.sh/${helm_filename}.sha256" -o "${tmp_helm_filename}.sha256"
curl -sSL "https://github.com/helm/helm/releases/download/${HELM_VERSION}/${helm_filename}.sha256.asc" -o "${tmp_helm_filename}.sha256.asc"
if ! gpg --verify "${tmp_helm_filename}.sha256.asc" > /tmp/helm/gnupg/verify.log 2>&1; then
echo "Verification failed!"
cat /tmp/helm/gnupg/verify.log
exit 1
fi
HELM_SHA256="$(cat "${tmp_helm_filename}.sha256")"
fi
([ "${HELM_SHA256}" = "dev-mode" ] || (echo "${HELM_SHA256} *${tmp_helm_filename}" | sha256sum -c -))
tar xf "${tmp_helm_filename}" -C /tmp/helm
mv -f "/tmp/helm/linux-${architecture}/helm" /usr/local/bin/
chmod 0755 /usr/local/bin/helm
rm -rf /tmp/helm
if ! type helm > /dev/null 2>&1; then
echo '(!) Helm installation failed!'
exit 1
fi
# Install Minikube, verify checksum
if [ "${MINIKUBE_VERSION}" != "none" ]; then
echo "Downloading minikube..."
if [ "${MINIKUBE_VERSION}" = "latest" ] || [ "${MINIKUBE_VERSION}" = "lts" ] || [ "${MINIKUBE_VERSION}" = "current" ] || [ "${MINIKUBE_VERSION}" = "stable" ]; then
MINIKUBE_VERSION="latest"
else
find_version_from_git_tags MINIKUBE_VERSION https://github.com/kubernetes/minikube
if [ "${MINIKUBE_VERSION::1}" != "v" ]; then
MINIKUBE_VERSION="v${MINIKUBE_VERSION}"
fi
fi
# latest is also valid in the download URLs
curl -sSL -o /usr/local/bin/minikube "https://storage.googleapis.com/minikube/releases/${MINIKUBE_VERSION}/minikube-linux-${architecture}"
chmod 0755 /usr/local/bin/minikube
if [ "$MINIKUBE_SHA256" = "automatic" ]; then
MINIKUBE_SHA256="$(curl -sSL "https://storage.googleapis.com/minikube/releases/${MINIKUBE_VERSION}/minikube-linux-${architecture}.sha256")"
fi
([ "${MINIKUBE_SHA256}" = "dev-mode" ] || (echo "${MINIKUBE_SHA256} */usr/local/bin/minikube" | sha256sum -c -))
if ! type minikube > /dev/null 2>&1; then
echo '(!) minikube installation failed!'
exit 1
fi
fi
if ! type docker > /dev/null 2>&1; then
echo -e '\n(*) Warning: The docker command was not found.\n\nYou can use one of the following scripts to install it:\n\nhttps://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/docker-in-docker.md\n\nor\n\nhttps://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/docker.md'
fi
echo -e "\nDone!"
-1
View File
@@ -1 +0,0 @@
VERSION='dev'
@@ -1,141 +0,0 @@
#!/bin/bash
#-------------------------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
#-------------------------------------------------------------------------------------------------------------
#
# Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/node.md
# Maintainer: The VS Code and Codespaces Teams
#
# Syntax: ./node-debian.sh [directory to install nvm] [node version to install (use "none" to skip)] [non-root user] [Update rc files flag]
export NVM_DIR=${1:-"/usr/local/share/nvm"}
export NODE_VERSION=${2:-"lts"}
USERNAME=${3:-"automatic"}
UPDATE_RC=${4:-"true"}
export NVM_VERSION="0.38.0"
set -e
if [ "$(id -u)" -ne 0 ]; then
echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
exit 1
fi
# Ensure that login shells get the correct path if the user updated the PATH using ENV.
rm -f /etc/profile.d/00-restore-env.sh
echo "export PATH=${PATH//$(sh -lc 'echo $PATH')/\$PATH}" > /etc/profile.d/00-restore-env.sh
chmod +x /etc/profile.d/00-restore-env.sh
# Determine the appropriate non-root user
if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then
USERNAME=""
POSSIBLE_USERS=("vscode" "node" "codespace" "$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)")
for CURRENT_USER in ${POSSIBLE_USERS[@]}; do
if id -u ${CURRENT_USER} > /dev/null 2>&1; then
USERNAME=${CURRENT_USER}
break
fi
done
if [ "${USERNAME}" = "" ]; then
USERNAME=root
fi
elif [ "${USERNAME}" = "none" ] || ! id -u ${USERNAME} > /dev/null 2>&1; then
USERNAME=root
fi
updaterc() {
if [ "${UPDATE_RC}" = "true" ]; then
echo "Updating /etc/bash.bashrc and /etc/zsh/zshrc..."
echo -e "$1" >> /etc/bash.bashrc
if [ -f "/etc/zsh/zshrc" ]; then
echo -e "$1" >> /etc/zsh/zshrc
fi
fi
}
# Function to run apt-get if needed
apt_get_update_if_needed()
{
if [ ! -d "/var/lib/apt/lists" ] || [ "$(ls /var/lib/apt/lists/ | wc -l)" = "0" ]; then
echo "Running apt-get update..."
apt-get update
else
echo "Skipping apt-get update."
fi
}
# Checks if packages are installed and installs them if not
check_packages() {
if ! dpkg -s "$@" > /dev/null 2>&1; then
apt_get_update_if_needed
apt-get -y install --no-install-recommends "$@"
fi
}
# Ensure apt is in non-interactive to avoid prompts
export DEBIAN_FRONTEND=noninteractive
# Install dependencies
check_packages apt-transport-https curl ca-certificates tar gnupg2
# Install yarn
if type yarn > /dev/null 2>&1; then
echo "Yarn already installed."
else
# Import key safely (new method rather than deprecated apt-key approach) and install
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor > /usr/share/keyrings/yarn-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/yarn-archive-keyring.gpg] https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list
apt-get update
apt-get -y install --no-install-recommends yarn
fi
# Adjust node version if required
if [ "${NODE_VERSION}" = "none" ]; then
export NODE_VERSION=
elif [ "${NODE_VERSION}" = "lts" ]; then
export NODE_VERSION="lts/*"
fi
# Install the specified node version if NVM directory already exists, then exit
if [ -d "${NVM_DIR}" ]; then
echo "NVM already installed."
if [ "${NODE_VERSION}" != "" ]; then
su ${USERNAME} -c ". $NVM_DIR/nvm.sh && nvm install ${NODE_VERSION} && nvm clear-cache"
fi
exit 0
fi
# Create nvm group, nvm dir, and set sticky bit
if ! cat /etc/group | grep -e "^nvm:" > /dev/null 2>&1; then
groupadd -r nvm
fi
umask 0002
usermod -a -G nvm ${USERNAME}
mkdir -p ${NVM_DIR}
chown :nvm ${NVM_DIR}
chmod g+s ${NVM_DIR}
su ${USERNAME} -c "$(cat << EOF
set -e
umask 0002
# Do not update profile - we'll do this manually
export PROFILE=/dev/null
curl -so- https://raw.githubusercontent.com/nvm-sh/nvm/v${NVM_VERSION}/install.sh | bash
source ${NVM_DIR}/nvm.sh
if [ "${NODE_VERSION}" != "" ]; then
nvm alias default ${NODE_VERSION}
fi
nvm clear-cache
EOF
)" 2>&1
# Update rc files
if [ "${UPDATE_RC}" = "true" ]; then
updaterc "$(cat <<EOF
export NVM_DIR="${NVM_DIR}"
[ -s "\$NVM_DIR/nvm.sh" ] && . "\$NVM_DIR/nvm.sh"
[ -s "\$NVM_DIR/bash_completion" ] && . "\$NVM_DIR/bash_completion"
EOF
)"
fi
echo "Done!"
@@ -1,307 +0,0 @@
#!/usr/bin/env bash
#-------------------------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
#-------------------------------------------------------------------------------------------------------------
#
# Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/python.md
# Maintainer: The VS Code and Codespaces Teams
#
# Syntax: ./python-debian.sh [Python Version] [Python intall path] [PIPX_HOME] [non-root user] [Update rc files flag] [install tools]
PYTHON_VERSION=${1:-"latest"}
PYTHON_INSTALL_PATH=${2:-"/usr/local/python"}
export PIPX_HOME=${3:-"/usr/local/py-utils"}
USERNAME=${4:-"automatic"}
UPDATE_RC=${5:-"true"}
INSTALL_PYTHON_TOOLS=${6:-"true"}
USE_PPA_IF_AVAILABLE=${7:-"true"}
DEADSNAKES_PPA_ARCHIVE_GPG_KEY="F23C5A6CF475977595C89F51BA6932366A755776"
PYTHON_SOURCE_GPG_KEYS="64E628F8D684696D B26995E310250568 2D347EA6AA65421D FB9921286F5E1540 3A5CA953F73C700D 04C367C218ADD4FF 0EDDC5F26A45C816 6AF053F07D9DC8D2 C9BE28DEE6DF025C 126EB563A74B06BF D9866941EA5BBD71 ED9D77D5"
GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com:80
keyserver hkps://keys.openpgp.org
keyserver hkp://keyserver.pgp.com"
set -e
if [ "$(id -u)" -ne 0 ]; then
echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
exit 1
fi
# Ensure that login shells get the correct path if the user updated the PATH using ENV.
rm -f /etc/profile.d/00-restore-env.sh
echo "export PATH=${PATH//$(sh -lc 'echo $PATH')/\$PATH}" > /etc/profile.d/00-restore-env.sh
chmod +x /etc/profile.d/00-restore-env.sh
# Determine the appropriate non-root user
if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then
USERNAME=""
POSSIBLE_USERS=("vscode" "node" "codespace" "$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)")
for CURRENT_USER in ${POSSIBLE_USERS[@]}; do
if id -u ${CURRENT_USER} > /dev/null 2>&1; then
USERNAME=${CURRENT_USER}
break
fi
done
if [ "${USERNAME}" = "" ]; then
USERNAME=root
fi
elif [ "${USERNAME}" = "none" ] || ! id -u ${USERNAME} > /dev/null 2>&1; then
USERNAME=root
fi
updaterc() {
if [ "${UPDATE_RC}" = "true" ]; then
echo "Updating /etc/bash.bashrc and /etc/zsh/zshrc..."
echo -e "$1" >> /etc/bash.bashrc
if [ -f "/etc/zsh/zshrc" ]; then
echo -e "$1" >> /etc/zsh/zshrc
fi
fi
}
# Get central common setting
get_common_setting() {
if [ "${common_settings_file_loaded}" != "true" ]; then
curl -sfL "https://aka.ms/vscode-dev-containers/script-library/settings.env" 2>/dev/null -o /tmp/vsdc-settings.env || echo "Could not download settings file. Skipping."
common_settings_file_loaded=true
fi
if [ -f "/tmp/vsdc-settings.env" ]; then
local multi_line=""
if [ "$2" = "true" ]; then multi_line="-z"; fi
local result="$(grep ${multi_line} -oP "$1=\"?\K[^\"]+" /tmp/vsdc-settings.env | tr -d '\0')"
if [ ! -z "${result}" ]; then declare -g $1="${result}"; fi
fi
echo "$1=${!1}"
}
# Import the specified key in a variable name passed in as
receive_gpg_keys() {
get_common_setting $1
local keys=${!1}
get_common_setting GPG_KEY_SERVERS true
local keyring_args=""
if [ ! -z "$2" ]; then
mkdir -p "$(dirname \"$2\")"
keyring_args="--no-default-keyring --keyring $2"
fi
# Use a temporary locaiton for gpg keys to avoid polluting image
export GNUPGHOME="/tmp/tmp-gnupg"
mkdir -p ${GNUPGHOME}
chmod 700 ${GNUPGHOME}
echo -e "disable-ipv6\n${GPG_KEY_SERVERS}" > ${GNUPGHOME}/dirmngr.conf
# GPG key download sometimes fails for some reason and retrying fixes it.
local retry_count=0
local gpg_ok="false"
set +e
until [ "${gpg_ok}" = "true" ] || [ "${retry_count}" -eq "5" ];
do
echo "(*) Downloading GPG key..."
( echo "${keys}" | xargs -n 1 gpg -q ${keyring_args} --recv-keys) 2>&1 && gpg_ok="true"
if [ "${gpg_ok}" != "true" ]; then
echo "(*) Failed getting key, retring in 10s..."
(( retry_count++ ))
sleep 10s
fi
done
set -e
if [ "${gpg_ok}" = "false" ]; then
echo "(!) Failed to install rvm."
exit 1
fi
}
# Figure out correct version of a three part version number is not passed
find_version_from_git_tags() {
local variable_name=$1
local requested_version=${!variable_name}
if [ "${requested_version}" = "none" ]; then return; fi
local repository=$2
local prefix=${3:-"tags/v"}
local separator=${4:-"."}
local last_part_optional=${5:-"false"}
if [ "$(echo "${requested_version}" | grep -o "." | wc -l)" != "2" ]; then
local escaped_separator=${separator//./\\.}
local last_part
if [ "${last_part_optional}" = "true" ]; then
last_part="(${escaped_separator}[0-9]+)?"
else
last_part="${escaped_separator}[0-9]+"
fi
local regex="${prefix}\\K[0-9]+${escaped_separator}[0-9]+${last_part}$"
local version_list="$(git ls-remote --tags ${repository} | grep -oP "${regex}" | tr -d ' ' | tr "${separator}" "." | sort -rV)"
if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ] || [ "${requested_version}" = "lts" ]; then
declare -g ${variable_name}="$(echo "${version_list}" | head -n 1)"
else
set +e
declare -g ${variable_name}="$(echo "${version_list}" | grep -E -m 1 "^${requested_version//./\\.}([\\.\\s]|$)")"
set -e
fi
fi
if [ -z "${!variable_name}" ] || ! echo "${version_list}" | grep "^${!variable_name//./\\.}$" > /dev/null 2>&1; then
echo -e "Invalid ${variable_name} value: ${requested_version}\nValid values:\n${version_list}" >&2
exit 1
fi
echo "${variable_name}=${!variable_name}"
}
# Function to run apt-get if needed
apt_get_update_if_needed()
{
if [ ! -d "/var/lib/apt/lists" ] || [ "$(ls /var/lib/apt/lists/ | wc -l)" = "0" ]; then
echo "Running apt-get update..."
apt-get update
else
echo "Skipping apt-get update."
fi
}
# Checks if packages are installed and installs them if not
check_packages() {
if ! dpkg -s "$@" > /dev/null 2>&1; then
apt_get_update_if_needed
apt-get -y install --no-install-recommends "$@"
fi
}
install_from_ppa() {
local requested_version="python${PYTHON_VERSION}"
echo "Using PPA to install Python..."
check_packages apt-transport-https curl ca-certificates gnupg2
receive_gpg_keys DEADSNAKES_PPA_ARCHIVE_GPG_KEY /usr/share/keyrings/deadsnakes-archive-keyring.gpg
echo -e "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/deadsnakes-archive-keyring.gpg] http://ppa.launchpad.net/deadsnakes/ppa/ubuntu ${VERSION_CODENAME} main\ndeb-src [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/deadsnakes-archive-keyring.gpg] http://ppa.launchpad.net/deadsnakes/ppa/ubuntu ${VERSION_CODENAME} main" > /etc/apt/sources.list.d/deadsnakes-ppa.list
apt-get update
if [ "${PYTHON_VERSION}" = "latest" ] || [ "${PYTHON_VERSION}" = "current" ] || [ "${PYTHON_VERSION}" = "lts" ]; then
requested_version="$(apt-cache search '^python3\.[0-9]$' | grep -oE '^python3\.[0-9]' | sort -rV | head -n 1)"
echo "Using ${requested_version} in place of ${PYTHON_VERSION}."
fi
apt-get -y install ${requested_version}
rm -rf /tmp/tmp-gnupg
exit 0
}
install_from_source() {
if [ -d "${PYTHON_INSTALL_PATH}" ]; then
echo "Path ${PYTHON_INSTALL_PATH} already exists. Remove this existing path or select a different one."
exit 1
else
echo "Building Python ${PYTHON_VERSION} from source..."
# Install prereqs if missing
check_packages curl ca-certificates tar make build-essential libssl-dev zlib1g-dev \
wget libbz2-dev libreadline-dev libxml2-dev xz-utils tk-dev gnupg2 \
libxmlsec1-dev libsqlite3-dev libffi-dev liblzma-dev llvm dirmngr
if ! type git > /dev/null 2>&1; then
apt_get_update_if_needed
apt-get -y install --no-install-recommends git
fi
# Find version using soft match
find_version_from_git_tags PYTHON_VERSION "https://github.com/python/cpython"
# Download tgz of source
mkdir -p /tmp/python-src "${PYTHON_INSTALL_PATH}"
cd /tmp/python-src
TGZ_FILENAME="Python-${PYTHON_VERSION}.tgz"
TGZ_URL="https://www.python.org/ftp/python/${PYTHON_VERSION}/${TGZ_FILENAME}"
echo "Downloading ${TGZ_FILENAME}..."
curl -sSL -o "/tmp/python-src/${TGZ_FILENAME}" "${TGZ_URL}"
# Verify signature
if [ "${SKIP_SIGNATURE_CHECK}" != "true" ]; then
receive_gpg_keys PYTHON_SOURCE_GPG_KEYS
echo "Downloading ${TGZ_FILENAME}.asc..."
curl -sSL -o "/tmp/python-src/${TGZ_FILENAME}.asc" "${TGZ_URL}.asc"
gpg --verify "${TGZ_FILENAME}.asc"
fi
# Update min protocol for testing only - https://bugs.python.org/issue41561
cp /etc/ssl/openssl.cnf /tmp/python-src/
sed -i -E 's/MinProtocol[=\ ]+.*/MinProtocol = TLSv1.0/g' /tmp/python-src/openssl.cnf
export OPENSSL_CONF=/tmp/python-src/openssl.cnf
# Untar and build
tar -xzf "/tmp/python-src/${TGZ_FILENAME}" -C "/tmp/python-src" --strip-components=1
./configure --prefix="${PYTHON_INSTALL_PATH}" --enable-optimizations --with-ensurepip=install
make -j 8
make install
cd /tmp
rm -rf /tmp/python-src ${GNUPGHOME} /tmp/vscdc-settings.env
chown -R ${USERNAME} "${PYTHON_INSTALL_PATH}"
ln -s ${PYTHON_INSTALL_PATH}/bin/python3 ${PYTHON_INSTALL_PATH}/bin/python
ln -s ${PYTHON_INSTALL_PATH}/bin/pip3 ${PYTHON_INSTALL_PATH}/bin/pip
ln -s ${PYTHON_INSTALL_PATH}/bin/idle3 ${PYTHON_INSTALL_PATH}/bin/idle
ln -s ${PYTHON_INSTALL_PATH}/bin/pydoc3 ${PYTHON_INSTALL_PATH}/bin/pydoc
ln -s ${PYTHON_INSTALL_PATH}/bin/python3-config ${PYTHON_INSTALL_PATH}/bin/python-config
updaterc "export PATH=${PYTHON_INSTALL_PATH}/bin:\${PATH}"
fi
}
# Ensure apt is in non-interactive to avoid prompts
export DEBIAN_FRONTEND=noninteractive
# Install python from source if needed
if [ "${PYTHON_VERSION}" != "none" ]; then
# Source /etc/os-release to get OS info
. /etc/os-release
# If ubuntu, PPAs allowed - install from there
if [ "${ID}" = "ubuntu" ] && [ "${USE_PPA_IF_AVAILABLE}" = "true" ]; then
install_from_ppa
else
install_from_source
fi
fi
# If not installing python tools, exit
if [ "${INSTALL_PYTHON_TOOLS}" != "true" ]; then
echo "Done!"
exit 0;
fi
DEFAULT_UTILS="\
pylint \
flake8 \
autopep8 \
black \
yapf \
mypy \
pydocstyle \
pycodestyle \
bandit \
pipenv \
virtualenv"
export PIPX_BIN_DIR=${PIPX_HOME}/bin
export PATH=${PYTHON_INSTALL_PATH}/bin:${PIPX_BIN_DIR}:${PATH}
# Update pip
echo "Updating pip..."
python3 -m pip install --no-cache-dir --upgrade pip
# Create pipx group, dir, and set sticky bit
if ! cat /etc/group | grep -e "^pipx:" > /dev/null 2>&1; then
groupadd -r pipx
fi
usermod -a -G pipx ${USERNAME}
umask 0002
mkdir -p ${PIPX_BIN_DIR}
chown :pipx ${PIPX_HOME} ${PIPX_BIN_DIR}
chmod g+s ${PIPX_HOME} ${PIPX_BIN_DIR}
# Install tools
echo "Installing Python tools..."
export PYTHONUSERBASE=/tmp/pip-tmp
export PIP_CACHE_DIR=/tmp/pip-tmp/cache
pip3 install --disable-pip-version-check --no-warn-script-location --no-cache-dir --user pipx
/tmp/pip-tmp/bin/pipx install --pip-args=--no-cache-dir pipx
echo "${DEFAULT_UTILS}" | xargs -n 1 /tmp/pip-tmp/bin/pipx install --system-site-packages --pip-args '--no-cache-dir --force-reinstall'
rm -rf /tmp/pip-tmp
updaterc "$(cat << EOF
export PIPX_HOME="${PIPX_HOME}"
export PIPX_BIN_DIR="${PIPX_BIN_DIR}"
if [[ "\${PATH}" != *"\${PIPX_BIN_DIR}"* ]]; then export PATH="\${PATH}:\${PIPX_BIN_DIR}"; fi
EOF
)"
@@ -1,13 +0,0 @@
#!/usr/bin/env bash
# k3d
# v5 RC is needed to deterministically set the Registry port. Should be replaces with official release
curl -s https://raw.githubusercontent.com/rancher/k3d/main/install.sh | TAG=v5.0.0-rc.4 bash
# kustomize
pushd /tmp
curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
popd
sudo mv /tmp/kustomize /usr/local/bin/
@@ -1,46 +0,0 @@
#!/usr/bin/env bash
# install Krew
# TODO (dans): ditch krew and just download the latest binaries on the path in Dockerfile
(
set -x; cd "$(mktemp -d)" &&
OS="$(uname | tr '[:upper:]' '[:lower:]')" &&
ARCH="$(uname -m | sed -e 's/x86_64/amd64/' -e 's/\(arm\)\(64\)\?.*/\1\2/' -e 's/aarch64$/arm64/')" &&
curl -fsSLO "https://github.com/kubernetes-sigs/krew/releases/latest/download/krew.tar.gz" &&
tar zxvf krew.tar.gz &&
KREW=./krew-"${OS}_${ARCH}" &&
"$KREW" install krew
)
# install krew plugins
kubectl krew install schemahero
kubectl krew install support-bundle
kubectl krew install preflights
kubectl krew install view-secret
# Make the cache from master branch
pushd /tmp
git clone https://github.com/replicatedhq/troubleshoot.git
pushd troubleshoot
# TODO (dans): find a way to cache images on image build
go mod download
popd
rm -rf kots
popd
# Clone any extra repos here
# Autocomplete Kubernetes
cat >> ~/.zshrc << EOF
source <(kubectl completion zsh)
alias k=kubectl
complete -F __start_kubectl k
EOF
# Set Git Editor Preference
cat >> ~/.zshrc << EOF
export VISUAL=vim
export EDITOR="$VISUAL"
EOF
@@ -1,16 +0,0 @@
#!/bin/bash
# modified from https://github.com/microsoft/vscode-dev-containers/blob/main/containers/codespaces-linux/.devcontainer/setup-user.sh
# not part of the standard script library
USERNAME=${1:-codespace}
SECURE_PATH_BASE=${2:-$PATH}
echo "Defaults secure_path=\"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/bin:${SECURE_PATH_BASE}\"" >> /etc/sudoers.d/securepath
# Add user to a Docker group
sudo -u ${USERNAME} mkdir /home/${USERNAME}/.vsonline
groupadd -g 800 docker
usermod -a -G docker ${USERNAME}
# Create user's .local/bin
sudo -u ${USERNAME} mkdir -p /home/${USERNAME}/.local/bin
@@ -1,165 +0,0 @@
#!/usr/bin/env bash
#-------------------------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
#-------------------------------------------------------------------------------------------------------------
#
# Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/sshd.md
# Maintainer: The VS Code and Codespaces Teams
#
# Syntax: ./sshd-debian.sh [SSH Port (don't use 22)] [non-root user] [start sshd now flag] [new password for user] [fix environment flag]
#
# Note: You can change your user's password with "sudo passwd $(whoami)" (or just "passwd" if running as root).
SSHD_PORT=${1:-"2222"}
USERNAME=${2:-"automatic"}
START_SSHD=${3:-"false"}
NEW_PASSWORD=${4:-"skip"}
FIX_ENVIRONMENT=${5:-"true"}
set -e
if [ "$(id -u)" -ne 0 ]; then
echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
exit 1
fi
# Determine the appropriate non-root user
if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then
USERNAME=""
POSSIBLE_USERS=("vscode" "node" "codespace" "$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)")
for CURRENT_USER in ${POSSIBLE_USERS[@]}; do
if id -u ${CURRENT_USER} > /dev/null 2>&1; then
USERNAME=${CURRENT_USER}
break
fi
done
if [ "${USERNAME}" = "" ]; then
USERNAME=root
fi
elif [ "${USERNAME}" = "none" ] || ! id -u ${USERNAME} > /dev/null 2>&1; then
USERNAME=root
fi
# Function to run apt-get if needed
apt_get_update_if_needed()
{
if [ ! -d "/var/lib/apt/lists" ] || [ "$(ls /var/lib/apt/lists/ | wc -l)" = "0" ]; then
echo "Running apt-get update..."
apt-get update
else
echo "Skipping apt-get update."
fi
}
# Checks if packages are installed and installs them if not
check_packages() {
if ! dpkg -s "$@" > /dev/null 2>&1; then
apt_get_update_if_needed
apt-get -y install --no-install-recommends "$@"
fi
}
# Ensure apt is in non-interactive to avoid prompts
export DEBIAN_FRONTEND=noninteractive
# Install openssh-server openssh-client
check_packages openssh-server openssh-client lsof
# Generate password if new password set to the word "random"
if [ "${NEW_PASSWORD}" = "random" ]; then
NEW_PASSWORD="$(openssl rand -hex 16)"
EMIT_PASSWORD="true"
elif [ "${NEW_PASSWORD}" != "skip" ]; then
# If new password not set to skip, set it for the specified user
echo "${USERNAME}:${NEW_PASSWORD}" | chpasswd
fi
# Add user to ssh group
if [ "${USERNAME}" != "root" ]; then
usermod -aG ssh ${USERNAME}
fi
# Setup sshd
mkdir -p /var/run/sshd
sed -i 's/session\s*required\s*pam_loginuid\.so/session optional pam_loginuid.so/g' /etc/pam.d/sshd
sed -i 's/#*PermitRootLogin prohibit-password/PermitRootLogin yes/g' /etc/ssh/sshd_config
sed -i -E "s/#*\s*Port\s+.+/Port ${SSHD_PORT}/g" /etc/ssh/sshd_config
# Need to UsePAM so /etc/environment is processed
sed -i -E "s/#?\s*UsePAM\s+.+/UsePAM yes/g" /etc/ssh/sshd_config
# Script to store variables that exist at the time the ENTRYPOINT is fired
store_env_script="$(cat << 'EOF'
# Wire in codespaces secret processing to zsh if present (since may have been added to image after script was run)
if [ -f /etc/zsh/zlogin ] && ! grep '/etc/profile.d/00-restore-secrets.sh' /etc/zsh/zlogin > /dev/null 2>&1; then
echo -e "if [ -f /etc/profile.d/00-restore-secrets.sh ]; then . /etc/profile.d/00-restore-secrets.sh; fi\n$(cat /etc/zsh/zlogin 2>/dev/null || echo '')" | sudoIf tee /etc/zsh/zlogin > /dev/null
fi
EOF
)"
# Script to ensure login shells get the latest Codespaces secrets
restore_secrets_script="$(cat << 'EOF'
#!/bin/sh
if [ "${CODESPACES}" != "true" ] || [ "${VSCDC_FIXED_SECRETS}" = "true" ] || [ ! -z "${GITHUB_CODESPACES_TOKEN}" ]; then
# Not codespaces, already run, or secrets already in environment, so return
return
fi
if [ -f /workspaces/.codespaces/shared/.env ]; then
set -o allexport
. /workspaces/.codespaces/shared/.env
set +o allexport
fi
export VSCDC_FIXED_SECRETS=true
EOF
)"
# Write out a scripts that can be referenced as an ENTRYPOINT to auto-start sshd and fix login environments
tee /usr/local/share/ssh-init.sh > /dev/null \
<< 'EOF'
#!/usr/bin/env bash
# This script is intended to be run as root with a container that runs as root (even if you connect with a different user)
# However, it supports running as a user other than root if passwordless sudo is configured for that same user.
set -e
sudoIf()
{
if [ "$(id -u)" -ne 0 ]; then
sudo "$@"
else
"$@"
fi
}
EOF
if [ "${FIX_ENVIRONMENT}" = "true" ]; then
echo "${store_env_script}" >> /usr/local/share/ssh-init.sh
echo "${restore_secrets_script}" > /etc/profile.d/00-restore-secrets.sh
chmod +x /etc/profile.d/00-restore-secrets.sh
# Wire in zsh if present
if type zsh > /dev/null 2>&1; then
echo -e "if [ -f /etc/profile.d/00-restore-secrets.sh ]; then . /etc/profile.d/00-restore-secrets.sh; fi\n$(cat /etc/zsh/zlogin 2>/dev/null || echo '')" > /etc/zsh/zlogin
fi
fi
tee -a /usr/local/share/ssh-init.sh > /dev/null \
<< 'EOF'
# ** Start SSH server **
sudoIf /etc/init.d/ssh start 2>&1 | sudoIf tee /tmp/sshd.log > /dev/null
set +e
exec "$@"
EOF
chmod +x /usr/local/share/ssh-init.sh
# If we should start sshd now, do so
if [ "${START_SSHD}" = "true" ]; then
/usr/local/share/ssh-init.sh
fi
# Output success details
echo -e "Done!\n\n- Port: ${SSHD_PORT}\n- User: ${USERNAME}"
if [ "${EMIT_PASSWORD}" = "true" ]; then
echo "- Password: ${NEW_PASSWORD}"
fi
echo -e "\nForward port ${SSHD_PORT} to your local machine and run:\n\n ssh -p ${SSHD_PORT} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o GlobalKnownHostsFile=/dev/null ${USERNAME}@localhost\n"
@@ -1,8 +0,0 @@
#!/usr/bin/env bash
# Setup the cluster
k3d cluster create --config /etc/replicated/k3d-cluster.yaml --kubeconfig-update-default
# Clone any extra repos here
@@ -1,5 +0,0 @@
#!/usr/bin/env bash
# Start the cluster here
k3d cluster start replicated
-21
View File
@@ -1,21 +0,0 @@
# Lines starting with '#' are comments.
# Each line is a file pattern followed by one or more owners.
# More details are here: https://help.github.com/articles/about-codeowners/
# The '*' pattern is global owners.
# Order is important. The last matching pattern has the most precedence.
# The folders are ordered as follows:
# In each subsection folders are ordered first by depth, then alphabetically.
# This should make it easy to add new rules without breaking existing ones.
## RULES
* @replicatedhq/troubleshoot
*.md @replicatedhq/cre
go.mod
go.sum
/examples/sdk/helm-template/go.mod
/examples/sdk/helm-template/go.sum
+1 -1
View File
@@ -7,7 +7,7 @@ labels: 'epic'
# Design Proposal
Link to the [proposal](https://github.com/replicatedhq/troubleshoot/tree/main/design/template.md)
Link to the [proposal](https://github.com/replicatedhq/troubleshoot/tree/main/docs/design/template.md)
# Definition of done
+39
View File
@@ -0,0 +1,39 @@
name: 'Setup Go Environment'
description: 'Setup Go with caching and common environment variables'
inputs:
go-version-file:
description: 'Path to go.mod file'
required: false
default: 'go.mod'
outputs:
go-version:
description: 'The Go version that was installed'
value: ${{ steps.setup-go.outputs.go-version }}
cache-hit:
description: 'Whether the Go cache was hit'
value: ${{ steps.setup-go.outputs.cache-hit }}
runs:
using: 'composite'
steps:
- name: Setup Go
id: setup-go
uses: actions/setup-go@v5
with:
go-version-file: ${{ inputs.go-version-file }}
cache: true
- name: Set Go environment variables
shell: bash
run: |
echo "GOMAXPROCS=2" >> $GITHUB_ENV
echo "GOCACHE=$(go env GOCACHE)" >> $GITHUB_ENV
echo "GOMODCACHE=$(go env GOMODCACHE)" >> $GITHUB_ENV
- name: Print Go environment
shell: bash
run: |
echo "Go version: $(go version)"
echo "GOOS: $(go env GOOS)"
echo "GOARCH: $(go env GOARCH)"
echo "Cache directory: $(go env GOCACHE)"
echo "Module cache: $(go env GOMODCACHE)"
@@ -1,97 +0,0 @@
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."
-389
View File
@@ -1,389 +0,0 @@
name: build-test-deploy
on:
pull_request:
types:
- opened
- reopened
- synchronize
- ready_for_review
branches:
- main
push:
branches:
- "main"
tags:
- "v*.*.*"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
fail_if_pull_request_is_draft:
if: github.event.pull_request.draft == true
runs-on: ubuntu-20.04
steps:
- name: Fails in order to indicate that pull request needs to be marked as ready to review and unit tests workflow needs to pass.
run: exit 1
test:
runs-on: ubuntu-20.04
steps:
- uses: actions/setup-go@v5
with:
go-version: "1.21"
- name: setup env
run: |
echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV
echo "$(go env GOPATH)/bin" >> $GITHUB_PATH
shell: bash
- uses: actions/checkout@v4
- run: make test
test-integration:
runs-on: ubuntu-20.04
steps:
- uses: actions/setup-go@v5
with:
go-version: "1.21"
- name: setup env
run: |
echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV
echo "$(go env GOPATH)/bin" >> $GITHUB_PATH
shell: bash
- uses: actions/checkout@v4
- uses: replicatedhq/action-k3s@main
id: k3s
with:
version: v1.24.1-k3s1
- run: make test-integration
ensure-schemas-are-generated:
runs-on: ubuntu-latest
steps:
- uses: actions/setup-go@v5
with:
go-version: "1.21"
- name: setup env
run: |
echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV
echo "$(go env GOPATH)/bin" >> $GITHUB_PATH
shell: bash
- uses: actions/checkout@v4
with:
fetch-depth: 0
- run: make check-schemas
compile-preflight:
runs-on: ubuntu-latest
steps:
- uses: actions/setup-go@v5
with:
go-version: "1.21"
- name: setup env
run: |
echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV
echo "$(go env GOPATH)/bin" >> $GITHUB_PATH
shell: bash
- uses: actions/checkout@v4
- run: make generate preflight
- uses: actions/upload-artifact@v4
with:
name: preflight
path: bin/preflight
validate-preflight:
runs-on: ubuntu-latest
needs: compile-preflight
steps:
- uses: replicatedhq/action-k3s@main
id: k3s
with:
version: v1.23.6-k3s1
- name: Download preflight binary
uses: actions/download-artifact@v4
with:
name: preflight
path: bin/
- run: chmod +x bin/preflight
- run: |
set +e
./bin/preflight --interactive=false --format=json https://preflight.replicated.com > result.json
EXIT_CODE=$?
cat result.json
EXIT_STATUS=0
if [ $EXIT_CODE -ne 3 ]; then
echo "Expected exit code of 3 (some checks failed), got $EXIT_CODE"
EXIT_STATUS=1
fi
if grep -q "was not collected" result.json; then
echo "Some files were not collected"
EXIT_STATUS=1
fi
if (( `jq '.pass | length' result.json` < 1 )); then
echo "No passing preflights found"
EXIT_STATUS=1
fi
if (( `jq '.warn | length' result.json` < 1 )); then
echo "No warnings found"
EXIT_STATUS=1
fi
if (( `jq '.fail | length' result.json` < 1 )); then
echo "No failed preflights found"
EXIT_STATUS=1
fi
exit $EXIT_STATUS
validate-preflight-e2e:
runs-on: ubuntu-latest
needs: compile-preflight
steps:
- uses: actions/checkout@v4
- uses: replicatedhq/action-k3s@main
id: k3s
with:
version: v1.23.6-k3s1
- name: Download preflight binary
uses: actions/download-artifact@v4
with:
name: preflight
path: bin/
- run: chmod +x bin/preflight
- run: make preflight-e2e-test
run-examples:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: make run-examples
compile-supportbundle:
runs-on: ubuntu-latest
steps:
- uses: actions/setup-go@v5
with:
go-version: "1.21"
- name: setup env
run: |
echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV
echo "$(go env GOPATH)/bin" >> $GITHUB_PATH
shell: bash
- uses: actions/checkout@v4
- run: make generate support-bundle
- uses: actions/upload-artifact@v4
with:
name: support-bundle
path: bin/support-bundle
validate-supportbundle:
runs-on: ubuntu-latest
needs: compile-supportbundle
steps:
- uses: actions/checkout@v4
- uses: replicatedhq/action-k3s@main
id: k3s
with:
version: v1.23.6-k3s1
- name: Download support-bundle binary
uses: actions/download-artifact@v4
with:
name: support-bundle
path: bin/
- run: chmod +x bin/support-bundle
- run: ./bin/support-bundle ./examples/support-bundle/sample-collectors.yaml
- run: ./bin/support-bundle ./examples/support-bundle/sample-supportbundle.yaml
- run: ./bin/support-bundle https://kots.io
validate-supportbundle-e2e:
runs-on: ubuntu-latest
needs: compile-supportbundle
steps:
- uses: actions/checkout@v4
- uses: replicatedhq/action-k3s@main
id: k3s
with:
version: v1.23.6-k3s1
- name: Download support bundle binary
uses: actions/download-artifact@v4
with:
name: support-bundle
path: bin/
- run: chmod +x bin/support-bundle
- run: make support-bundle-e2e-test
validate-supportbundle-e2e-go-test:
runs-on: ubuntu-latest
needs: compile-supportbundle
steps:
- uses: actions/setup-go@v5
with:
go-version: "1.21"
- name: setup env
run: |
echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV
echo "$(go env GOPATH)/bin" >> $GITHUB_PATH
shell: bash
- uses: actions/checkout@v4
- name: Download support bundle binary
uses: actions/download-artifact@v4
with:
name: support-bundle
path: bin/
- run: chmod +x bin/support-bundle
- run: make support-bundle-e2e-go-test
compile-collect:
runs-on: ubuntu-latest
steps:
- uses: actions/setup-go@v5
with:
go-version: "1.21"
- name: setup env
run: |
echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV
echo "$(go env GOPATH)/bin" >> $GITHUB_PATH
shell: bash
- uses: actions/checkout@v4
- run: make generate collect
- uses: actions/upload-artifact@v4
with:
name: collect
path: bin/collect
goreleaser-test:
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/v') != true
strategy:
matrix:
goarch: [amd64, arm64]
goos: [darwin, linux, windows]
include:
- goarch: arm
goos: linux
- goarch: riscv64
goos: linux
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-go@v5
with:
go-version: "1.21"
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v5
with:
version: "v0.183.0"
args: build --rm-dist --snapshot --config deploy/.goreleaser.yaml --single-target
env:
GOARCH: ${{ matrix.goarch }}
GOOS: ${{ matrix.goos }}
goreleaser:
runs-on: ubuntu-latest
needs:
- validate-preflight
- validate-preflight-e2e
- validate-supportbundle
if: startsWith(github.ref, 'refs/tags/v')
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: azure/docker-login@v1
with:
username: ${{ secrets.DOCKERHUB_USER }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
- uses: actions/setup-go@v5
with:
go-version: "1.21"
- uses: sigstore/cosign-installer@v3
with:
# DO NOT USE v2 until we decide on whether to use Rekor or not
cosign-release: "v1.13.1" # Binary version to install
- name: Get Cosign Key
run: |
echo $COSIGN_KEY | base64 -d > ./cosign.key
env:
COSIGN_KEY: ${{secrets.COSIGN_KEY}}
- name: Generate SBOM
run: |
make sbom
env:
COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }}
COSIGN_KEY: ${{ secrets.COSIGN_KEY }}
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v5
with:
version: "v1.x" # Binary version to install
args: release --rm-dist --config deploy/.goreleaser.yaml
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Update new preflight version in krew-index
uses: rajatjindal/krew-release-bot@v0.0.46
with:
krew_template_file: deploy/krew/preflight.yaml
- name: Update new support-bundle version in krew-index
uses: rajatjindal/krew-release-bot@v0.0.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"
+163
View File
@@ -0,0 +1,163 @@
name: build-test
on:
pull_request:
types: [opened, reopened, synchronize, ready_for_review]
branches: [v1beta3]
push:
branches: [v1beta3]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
# Detect changes to optimize test execution
changes:
runs-on: ubuntu-latest
outputs:
go-files: ${{ steps.filter.outputs.go-files }}
preflight: ${{ steps.filter.outputs.preflight }}
support-bundle: ${{ steps.filter.outputs.support-bundle }}
examples: ${{ steps.filter.outputs.examples }}
steps:
- uses: actions/checkout@v5
- uses: dorny/paths-filter@v3
id: filter
with:
filters: |
go-files:
- '**/*.go'
- 'go.{mod,sum}'
- 'Makefile'
preflight:
- 'cmd/preflight/**'
- 'pkg/preflight/**'
support-bundle:
- 'cmd/troubleshoot/**'
- 'pkg/supportbundle/**'
# Lint
lint:
if: needs.changes.outputs.go-files == 'true'
needs: changes
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v5
- uses: ./.github/actions/setup-go
- name: Check go mod tidy
run: |
go mod tidy
git diff --exit-code go.mod go.sum || {
echo "::error::Please run 'go mod tidy' and commit changes"
exit 1
}
- name: Format and vet
run: |
make fmt
git diff --exit-code || {
echo "::error::Please run 'make fmt' and commit changes"
exit 1
}
make vet
# Unit and integration tests
test:
if: needs.changes.outputs.go-files == 'true'
needs: [changes, lint]
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v5
- uses: ./.github/actions/setup-go
- name: Setup K3s
uses: replicatedhq/action-k3s@main
with:
version: v1.31.2-k3s1
- name: Run tests
run: make test-integration
# Build binaries
build:
if: needs.changes.outputs.go-files == 'true'
needs: [changes, lint]
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v5
- uses: ./.github/actions/setup-go
- run: make build
- uses: actions/upload-artifact@v4
with:
name: binaries
path: bin/
retention-days: 1
# E2E tests
e2e:
if: needs.changes.outputs.go-files == 'true' || github.event_name == 'push'
needs: [changes, build]
runs-on: ubuntu-latest
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
include:
- name: preflight
target: preflight-e2e-test
needs-k3s: true
- name: support-bundle-shell
target: support-bundle-e2e-test
needs-k3s: true
- name: support-bundle-go
target: support-bundle-e2e-go-test
needs-k3s: false
steps:
- uses: actions/checkout@v5
- name: Setup K3s
if: matrix.needs-k3s
uses: replicatedhq/action-k3s@main
with:
version: v1.31.2-k3s1
- uses: actions/download-artifact@v4
with:
name: binaries
path: bin/
- run: chmod +x bin/*
- run: make ${{ matrix.target }}
# Success summary
success:
if: always()
needs: [lint, test, build, e2e]
runs-on: ubuntu-latest
steps:
- name: Check results
run: |
# Check if any required jobs failed
if [[ "${{ needs.lint.result }}" == "failure" ]] || \
[[ "${{ needs.test.result }}" == "failure" ]] || \
[[ "${{ needs.build.result }}" == "failure" ]] || \
[[ "${{ needs.e2e.result }}" == "failure" ]]; then
echo "::error::Some jobs failed or were cancelled"
exit 1
fi
# Check if any required jobs were cancelled
if [[ "${{ needs.lint.result }}" == "cancelled" ]] || \
[[ "${{ needs.test.result }}" == "cancelled" ]] || \
[[ "${{ needs.build.result }}" == "cancelled" ]] || \
[[ "${{ needs.e2e.result }}" == "cancelled" ]]; then
echo "::error::Some jobs failed or were cancelled"
exit 1
fi
echo "✅ All tests passed!"
-27
View File
@@ -1,27 +0,0 @@
name: Scan vulnerabilities
on:
schedule:
- cron: '0 0 * * *'
workflow_dispatch:
jobs:
scan_troubleshoot_files_systems:
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Run Trivy vulnerability scanner in repo mode
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
ignore-unfixed: true
format: 'sarif'
output: 'trivy-results.sarif'
severity: 'HIGH,CRITICAL'
- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: 'trivy-results.sarif'
-44
View File
@@ -1,44 +0,0 @@
on:
push:
branches:
- main
pull_request:
env:
TRIVY_VERSION: 0.44.1
name: License scan
jobs:
license:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: 1.21
- name: Install Go deps
run: go mod download
- name: Install trivy
run: |
wget https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/trivy_${TRIVY_VERSION}_Linux-64bit.deb
sudo dpkg -i trivy_${TRIVY_VERSION}_Linux-64bit.deb
- name: Create license report artifact
run: trivy fs --scanners license --skip-dirs ".github" . | tee license-report.txt
- name: Upload license report artifact
uses: actions/upload-artifact@v4
with:
name: license-report
path: license-report.txt
- name: Check for unknown licenses
run: trivy fs --scanners license --skip-dirs ".github" --exit-code 1 --severity UNKNOWN . || echo "::warning::Unknown licenses found, please verify"
- name: Check for forbidden licenses and fail
run: trivy fs --scanners license --skip-dirs ".github" --exit-code 1 --severity CRITICAL,HIGH .
+292
View File
@@ -0,0 +1,292 @@
name: Regression Test Suite
on:
push:
branches: [main, v1beta3]
pull_request:
types: [opened, synchronize, reopened]
workflow_dispatch:
inputs:
update_baselines:
description: 'Update baselines after run (use with caution)'
type: boolean
default: false
jobs:
regression-test:
runs-on: ubuntu-22.04
timeout-minutes: 25
steps:
# 1. SETUP
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch all history for git describe to work
- name: Create output directory
run: mkdir -p test/output
- name: Create k3s cluster
id: create-cluster
uses: replicatedhq/compatibility-actions/create-cluster@v1
with:
api-token: ${{ secrets.REPLICATED_API_TOKEN }}
kubernetes-distribution: k3s
cluster-name: regression-${{ github.run_id }}-${{ github.run_attempt }}
ttl: 25m
timeout-minutes: 5
- name: Configure kubeconfig
run: |
echo "${{ steps.create-cluster.outputs.cluster-kubeconfig }}" > $GITHUB_WORKSPACE/kubeconfig.yaml
echo "KUBECONFIG=$GITHUB_WORKSPACE/kubeconfig.yaml" >> $GITHUB_ENV
- name: Verify cluster access
run: kubectl get nodes -o wide
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version-file: go.mod
cache: true
cache-dependency-path: go.sum
- name: Build binaries
run: |
echo "Building preflight and support-bundle binaries..."
make bin/preflight bin/support-bundle
./bin/preflight version
./bin/support-bundle version
- name: Setup Python for comparison
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install Python dependencies
run: |
pip install pyyaml deepdiff
# 2. EXECUTE SPECS (in parallel)
- name: Run all specs in parallel
continue-on-error: true
run: |
echo "Running all 3 specs in parallel..."
# Run v1beta3 in background
(
echo "Starting preflight v1beta3..."
./bin/preflight \
examples/preflight/complex-v1beta3.yaml \
--values examples/preflight/values-complex-full.yaml \
--interactive=false \
--format=json \
--output=test/output/preflight-results-v1beta3.json 2>&1 | tee test/output/v1beta3.log || true
BUNDLE=$(ls -t preflightbundle-*.tar.gz 2>/dev/null | head -1)
if [ -n "$BUNDLE" ]; then
mv "$BUNDLE" test/output/preflight-v1beta3-bundle.tar.gz
echo "✓ v1beta3 bundle saved"
fi
) &
PID_V1BETA3=$!
# Run v1beta2 in background
(
echo "Starting preflight v1beta2..."
./bin/preflight \
examples/preflight/all-analyzers-v1beta2.yaml \
--interactive=false \
--format=json \
--output=test/output/preflight-results-v1beta2.json 2>&1 | tee test/output/v1beta2.log || true
BUNDLE=$(ls -t preflightbundle-*.tar.gz 2>/dev/null | head -1)
if [ -n "$BUNDLE" ]; then
mv "$BUNDLE" test/output/preflight-v1beta2-bundle.tar.gz
echo "✓ v1beta2 bundle saved"
fi
) &
PID_V1BETA2=$!
# Run support bundle in background
(
echo "Starting support bundle..."
./bin/support-bundle \
examples/collect/host/all-kubernetes-collectors.yaml \
--interactive=false \
--output=test/output/supportbundle.tar.gz 2>&1 | tee test/output/supportbundle.log || true
if [ -f test/output/supportbundle.tar.gz ]; then
echo "✓ Support bundle saved"
fi
) &
PID_SUPPORTBUNDLE=$!
# Wait for all to complete
echo "Waiting for all specs to complete..."
wait $PID_V1BETA3
wait $PID_V1BETA2
wait $PID_SUPPORTBUNDLE
echo "All specs completed!"
# Verify bundles exist
ls -lh test/output/*.tar.gz || echo "Warning: Some bundles may be missing"
# 3. COMPARE BUNDLES
- name: Compare preflight v1beta3 bundle
id: compare-v1beta3
continue-on-error: true
run: |
echo "Comparing v1beta3 preflight bundle against baseline..."
if [ ! -f test/baselines/preflight-v1beta3/baseline.tar.gz ]; then
echo "⚠ No baseline found for v1beta3 - skipping comparison"
echo "baseline_missing=true" >> $GITHUB_OUTPUT
exit 0
fi
python3 scripts/compare_bundles.py \
--baseline test/baselines/preflight-v1beta3/baseline.tar.gz \
--current test/output/preflight-v1beta3-bundle.tar.gz \
--rules scripts/compare_rules.yaml \
--report test/output/diff-report-v1beta3.json \
--spec-type preflight
- name: Compare preflight v1beta2 bundle
id: compare-v1beta2
continue-on-error: true
run: |
echo "Comparing v1beta2 preflight bundle against baseline..."
if [ ! -f test/baselines/preflight-v1beta2/baseline.tar.gz ]; then
echo "⚠ No baseline found for v1beta2 - skipping comparison"
echo "baseline_missing=true" >> $GITHUB_OUTPUT
exit 0
fi
python3 scripts/compare_bundles.py \
--baseline test/baselines/preflight-v1beta2/baseline.tar.gz \
--current test/output/preflight-v1beta2-bundle.tar.gz \
--rules scripts/compare_rules.yaml \
--report test/output/diff-report-v1beta2.json \
--spec-type preflight
- name: Compare support bundle
id: compare-supportbundle
continue-on-error: true
run: |
echo "Comparing support bundle against baseline..."
if [ ! -f test/baselines/supportbundle/baseline.tar.gz ]; then
echo "⚠ No baseline found for support bundle - skipping comparison"
echo "baseline_missing=true" >> $GITHUB_OUTPUT
exit 0
fi
python3 scripts/compare_bundles.py \
--baseline test/baselines/supportbundle/baseline.tar.gz \
--current test/output/supportbundle.tar.gz \
--rules scripts/compare_rules.yaml \
--report test/output/diff-report-supportbundle.json \
--spec-type supportbundle
# 4. REPORT RESULTS
- name: Generate summary report
if: always()
run: |
python3 scripts/generate_summary.py \
--reports test/output/diff-report-*.json \
--output-file $GITHUB_STEP_SUMMARY \
--output-console
- name: Upload test artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: regression-test-results-${{ github.run_id }}-${{ github.run_attempt }}
path: |
test/output/*.tar.gz
test/output/*.json
retention-days: 30
- name: Check for regressions
if: always()
run: |
echo "Checking comparison results..."
# Check if any comparisons failed
FAILURES=0
if [ "${{ steps.compare-v1beta3.outcome }}" == "failure" ] && [ "${{ steps.compare-v1beta3.outputs.baseline_missing }}" != "true" ]; then
echo "❌ v1beta3 comparison failed"
FAILURES=$((FAILURES + 1))
fi
if [ "${{ steps.compare-v1beta2.outcome }}" == "failure" ] && [ "${{ steps.compare-v1beta2.outputs.baseline_missing }}" != "true" ]; then
echo "❌ v1beta2 comparison failed"
FAILURES=$((FAILURES + 1))
fi
if [ "${{ steps.compare-supportbundle.outcome }}" == "failure" ] && [ "${{ steps.compare-supportbundle.outputs.baseline_missing }}" != "true" ]; then
echo "❌ Support bundle comparison failed"
FAILURES=$((FAILURES + 1))
fi
if [ $FAILURES -gt 0 ]; then
echo ""
echo "❌ $FAILURES regression(s) detected!"
echo "Review the comparison reports in the artifacts."
exit 1
else
echo "✅ All comparisons passed or skipped (no baseline)"
fi
# 5. UPDATE BASELINES (optional, manual trigger only)
- name: Update baselines
if: github.event.inputs.update_baselines == 'true' && github.event_name == 'workflow_dispatch'
run: |
echo "Updating baselines with current bundles..."
# Copy new bundles as baselines
if [ -f test/output/preflight-v1beta3-bundle.tar.gz ]; then
mkdir -p test/baselines/preflight-v1beta3
cp test/output/preflight-v1beta3-bundle.tar.gz test/baselines/preflight-v1beta3/baseline.tar.gz
echo "✓ Updated v1beta3 baseline"
fi
if [ -f test/output/preflight-v1beta2-bundle.tar.gz ]; then
mkdir -p test/baselines/preflight-v1beta2
cp test/output/preflight-v1beta2-bundle.tar.gz test/baselines/preflight-v1beta2/baseline.tar.gz
echo "✓ Updated v1beta2 baseline"
fi
if [ -f test/output/supportbundle.tar.gz ]; then
mkdir -p test/baselines/supportbundle
cp test/output/supportbundle.tar.gz test/baselines/supportbundle/baseline.tar.gz
echo "✓ Updated support bundle baseline"
fi
# Create metadata file
cat > test/baselines/metadata.json <<EOF
{
"updated_at": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
"git_sha": "${{ github.sha }}",
"k8s_version": "v1.28.3",
"workflow_run": "${{ github.run_id }}"
}
EOF
# Commit and push
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add test/baselines/
git commit -m "chore: update regression test baselines from run ${{ github.run_id }}"
git push
# 6. CLEANUP
- name: Remove cluster
if: always()
uses: replicatedhq/compatibility-actions/remove-cluster@v1
continue-on-error: true
with:
api-token: ${{ secrets.REPLICATED_API_TOKEN }}
cluster-id: ${{ steps.create-cluster.outputs.cluster-id }}
+48
View File
@@ -0,0 +1,48 @@
name: release
on:
push:
tags:
- 'v*'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: false
jobs:
goreleaser:
runs-on: troubleshoot_release
steps:
- name: Checkout
uses: actions/checkout@v5
with:
fetch-depth: 0
- uses: azure/docker-login@v2
with:
username: ${{ secrets.DOCKERHUB_USER }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
- uses: actions/setup-go@v6
with:
go-version-file: 'go.mod'
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v6
with:
version: "v2.12.3"
args: release --clean --config deploy/.goreleaser.yaml
env:
GITHUB_TOKEN: ${{ secrets.HOMEBREW_GITHUB_TOKEN }}
- name: Update new preflight version in krew-index
if: ${{ !contains(github.ref_name, '-') }}
uses: rajatjindal/krew-release-bot@v0.0.47
with:
krew_template_file: deploy/krew/preflight.yaml
- name: Update new support-bundle version in krew-index
if: ${{ !contains(github.ref_name, '-') }}
uses: rajatjindal/krew-release-bot@v0.0.47
with:
krew_template_file: deploy/krew/support-bundle.yaml
+8
View File
@@ -48,3 +48,11 @@ sbom/
# Ignore generated support bundles
*.tar.gz
!testdata/supportbundle/*.tar.gz
!test/baselines/**/baseline.tar.gz
# Ignore built binaries
troubleshoot
troubleshoot-test
cmd/troubleshoot/troubleshoot
cmd/*/troubleshoot
support-bundle
-13
View File
@@ -1,13 +0,0 @@
# https://golangci-lint.run/usage/configuration/#config-file
run:
allow-parallel-runners: true
timeout: 30s
linters:
enable:
- gocritic
- gocyclo
- gofmt
- gosec
- govet
-128
View File
@@ -1,128 +0,0 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
oss@replicated.com.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.
+7 -76
View File
@@ -1,12 +1,10 @@
# Contributing to Troubleshoot
Thank you for your interest in Troubleshoot, we welcome your participation. Please familiarize yourself with our [Code of Conduct](https://github.com/replicatedhq/troubleshoot/blob/main/CODE_OF_CONDUCT.md) prior to contributing. There are a number of ways to participate in Troubleshoot as outlined below:
Thank you for your interest in Troubleshoot, we welcome your participation. There are a number of ways to participate in Troubleshoot as outlined below:
# Community
For discussions about developing Troubleshoot, there's an [#app-troubleshoot channel in Kubernetes Slack](https://kubernetes.slack.com/channels/app-troubleshoot), plus IRC using [Libera](ircs://irc.libera.chat:6697/#troubleshoot) (#troubleshoot).
There are [community meetings](https://calendar.google.com/calendar/u/0?cid=Y19mMGx1aGhiZGtscGllOGo5dWpicXMwNnN1a0Bncm91cC5jYWxlbmRhci5nb29nbGUuY29t) on a regular basis, with a shared calendar and [public notes](https://hackmd.io/yZbotEHdTg6TfRZBzb8Tcg)
For discussions about developing Troubleshoot, there's an [#app-troubleshoot channel in Kubernetes Slack](https://kubernetes.slack.com/channels/app-troubleshoot).
## Issues
@@ -21,44 +19,15 @@ When implementing a new feature please review the [design principles](./docs/des
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)
1. Go (v1.24 or later)
2. For cluster-based collectors, you will need access to a Kubernetes cluster
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
5. You can now run `./bin/preflight` and/or `./bin/support-bundle` to use the code you've been writing
> Note: recent versions of Go support easy cross-compilation. For example, to cross-compile a Linux binary from MacOS:
> Note: to cross-compile a Linux binary from MacOS:
> `GOOS=linux GOARCH=amd64 make clean build`
6. Install [golangci-lint] linter and run `make lint` to execute additional code linters.
### Build automatically on save with `watch`
1. Install `npm`
2. Run `make watch` to build binaries automatically on saving. Note: you may still have to run `make schemas` if you've added API changes, like a new collector or analyzer type.
### Syncing to a test cluster with `watchrsync`
1. Install `npm`
2. Export `REMOTES=<user>@<ip>` so that `watchrsync` knows where to sync.
3. Maybe run `export GOOS=linux` and `export GOARCH=amd64` so that you build Linux binaries.
4. run `make watchrsync` to build and sync binaries automatically on saving.
```
ssh-add --apple-use-keychain ~/.ssh/google_compute_engine
export REMOTES=ada@35.229.61.56
export GOOS=linux
export GOARCH=amd64
make watchrsync
# bin/watchrsync.js
# make support-bundle
# go build -tags "netgo containers_image_ostree_stub exclude_graphdriver_devicemapper exclude_graphdriver_btrfs containers_image_openpgp" -installsuffix netgo -ldflags " -s -w -X github.com/replicatedhq/troubleshoot/pkg/version.version=`git describe --tags --dirty` -X github.com/replicatedhq/troubleshoot/pkg/version.gitSHA=`git rev-parse HEAD` -X github.com/replicatedhq/troubleshoot/pkg/version.buildTime=`date -u +"%Y-%m-%dT%H:%M:%SZ"` " -o bin/support-bundle github.com/replicatedhq/troubleshoot/cmd/troubleshoot
# rsync bin/support-bundle ada@35.229.61.56:
# date
# Tue May 16 14:14:13 EDT 2023
# synced
```
### Testing
To run the tests locally run the following:
@@ -104,42 +73,4 @@ More on profiling please visit https://go.dev/doc/diagnostics#profiling
## Contribution workflow
This is a rough outline of how to prepare a contribution:
- Create a fork of this repo.
- Create a topic branch from where you want to base your work (branched from `main` is a safe choice).
- Make commits of logical units.
- When your changes are ready to merge, squash your history to 1 commit.
- For example, if you want to squash your last 3 commits and write a new commit message:
```
git reset --soft HEAD~3 &&
git commit
```
- If you want to keep the previous commit messages and concatenate them all into a new commit, you can do something like this instead:
```
git reset --soft HEAD~3 &&
git commit --edit -m"$(git log --format=%B --reverse HEAD..HEAD@{1})"
```
- Push your changes to a topic branch in your fork of the repository.
- Submit a pull request to the original repository. It will be reviewed in a timely manner.
### Pull Requests
A pull request should address a single issue, feature or bug. For example, lets say you've written code that fixes two issues. That's great! However, you should submit two small pull requests, one for each issue as opposed to combining them into a single larger pull request. In general the size of the pull request should be kept small in order to make it easy for a reviewer to understand, and to minimize risks from integrating many changes at the same time. For example, if you are working on a large feature you should break it into several smaller PRs by implementing the feature as changes to several packages and submitting a separate pull request for each one. Squash commit history when preparing your PR so it merges as 1 commit.
Code submitted in pull requests must be properly documented, formatted and tested in order to be approved and merged. The following guidelines describe the things a reviewer will look for when they evaluate your pull request. Here's a tip. If your reviewer doesn't understand what the code is doing, they won't approve the pull request. Strive to make code clear and well documented. If possible, request a reviewer that has some context on the PR.
### Commit messages
Commit messages should follow the general guidelines:
- Breaking changes should be highlighted in the heading of the commit message.
- Commits should be clear about their purpose (and a single commit per thing that changed)
- Messages should be descriptive:
- First line, 50 chars or less, as a heading/title that people can find
- Then a paragraph explaining things
- Consider a footer with links to which bugs they fix etc, bearing in mind that Github does some of this magic already
We'd love to talk before you dig into a a large feature.
File diff suppressed because it is too large Load Diff
+18 -190
View File
@@ -34,20 +34,17 @@ define LDFLAGS
"
endef
BUILDFLAGS = -tags "netgo containers_image_ostree_stub exclude_graphdriver_devicemapper exclude_graphdriver_btrfs containers_image_openpgp" -installsuffix netgo
BUILDTAGS = "netgo containers_image_ostree_stub exclude_graphdriver_devicemapper exclude_graphdriver_btrfs containers_image_openpgp"
BUILDFLAGS = -tags ${BUILDTAGS} -installsuffix netgo
BUILDPATHS = ./pkg/... ./cmd/... ./internal/...
E2EPATHS = ./test/e2e/...
TESTFLAGS ?= -v -coverprofile cover.out
TESTFLAGS ?=
.DEFAULT_GOAL := all
all: clean build test
.PHONY: ffi
ffi: fmt vet
go build ${BUILDFLAGS} ${LDFLAGS} -o bin/troubleshoot.so -buildmode=c-shared ffi/main.go
.PHONY: test
test: generate fmt vet
test: fmt vet
if [ -n $(RUN) ]; then \
go test ${BUILDFLAGS} ${BUILDPATHS} ${TESTFLAGS} -run $(RUN); \
else \
@@ -57,17 +54,13 @@ test: generate fmt vet
# Go tests that require a K8s instance
# TODOLATER: merge with test, so we get unified coverage reports? it'll add 21~sec to the test job though...
.PHONY: test-integration
test-integration:
go test -v --tags "integration exclude_graphdriver_devicemapper exclude_graphdriver_btrfs" ${BUILDPATHS}
test-integration: fmt vet
go test -v --tags="integration exclude_graphdriver_devicemapper exclude_graphdriver_btrfs" ${BUILDPATHS}
.PHONY: preflight-e2e-test
preflight-e2e-test:
./test/validate-preflight-e2e.sh
.PHONY: run-examples
run-examples:
./test/run-examples.sh
.PHONY: support-bundle-e2e-test
support-bundle-e2e-test:
./test/validate-support-bundle-e2e.sh
@@ -80,37 +73,35 @@ support-bundle-e2e-go-test:
go test ${BUILDFLAGS} ${E2EPATHS} -v; \
fi
# Build all binaries in parallel ( -j )
rebuild: clean build
build: tidy
@echo "Build cli binaries"
$(MAKE) -j bin/support-bundle bin/preflight bin/analyze bin/collect
$(MAKE) bin/support-bundle bin/preflight
.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
bin/support-bundle:
# Only build when any of the files in SOURCES changes, or if bin/<file> is absent
MAKEFILE_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
SOURCES := $(shell find $(MAKEFILE_DIR) -type f \( -name "*.go" -o -name "go.mod" -o -name "go.sum" \))
bin/support-bundle: $(SOURCES)
go build ${BUILDFLAGS} ${LDFLAGS} -o bin/support-bundle github.com/replicatedhq/troubleshoot/cmd/troubleshoot
bin/preflight:
bin/preflight: $(SOURCES)
go build ${BUILDFLAGS} ${LDFLAGS} -o bin/preflight github.com/replicatedhq/troubleshoot/cmd/preflight
bin/analyze:
go build ${BUILDFLAGS} ${LDFLAGS} -o bin/analyze github.com/replicatedhq/troubleshoot/cmd/analyze
.PHONY: support-bundle
support-bundle: bin/support-bundle
bin/collect:
go build ${BUILDFLAGS} ${LDFLAGS} -o bin/collect github.com/replicatedhq/troubleshoot/cmd/collect
.PHONY: preflight
preflight: bin/preflight
.PHONY: fmt
fmt:
@@ -119,166 +110,3 @@ fmt:
.PHONY: vet
vet:
go vet ${BUILDFLAGS} ${BUILDPATHS}
.PHONY: generate
generate: controller-gen client-gen
$(CONTROLLER_GEN) \
object:headerFile=./hack/boilerplate.go.txt paths=./pkg/apis/...
$(CLIENT_GEN) \
--output-base=./../../../ \
--output-package=github.com/replicatedhq/troubleshoot/pkg/client \
--clientset-name troubleshootclientset \
--input-base github.com/replicatedhq/troubleshoot/pkg/apis \
--input troubleshoot/v1beta1 \
--input troubleshoot/v1beta2 \
-h ./hack/boilerplate.go.txt
.PHONY: openapischema
openapischema: controller-gen
controller-gen crd +output:dir=./config/crds paths=./pkg/apis/troubleshoot/v1beta1
controller-gen crd +output:dir=./config/crds paths=./pkg/apis/troubleshoot/v1beta2
check-schemas: generate schemas
@if [ -n "$(shell git status --short)" ]; then \
echo -e "\033[31mThe git repo is dirty :( Ensure all generated files are committed e.g CRD schema files\033[0;m"; \
git status --short; \
exit 1; \
fi
.PHONY: schemas
schemas: fmt vet openapischema 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 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
CONTROLLER_GEN=$(shell which controller-gen)
.PHONY: client-gen
client-gen:
go install k8s.io/code-generator/cmd/client-gen@v0.28.2
CLIENT_GEN=$(shell which client-gen)
.PHONY: release
release: export GITHUB_TOKEN = $(shell echo ${GITHUB_TOKEN_TROUBLESHOOT})
release:
curl -sL https://git.io/goreleaser | bash -s -- --rm-dist --config deploy/.goreleaser.yml
.PHONY: snapshot-release
snapshot-release:
curl -sL https://git.io/goreleaser | bash -s -- --rm-dist --snapshot --config deploy/.goreleaser.snapshot.yml
docker push replicated/troubleshoot:alpha
docker push replicated/preflight:alpha
.PHONY: local-release
local-release:
curl -sL https://git.io/goreleaser | bash -s -- --rm-dist --snapshot --config deploy/.goreleaser.yaml
docker tag replicated/troubleshoot:alpha localhost:32000/troubleshoot:alpha
docker tag replicated/preflight:alpha localhost:32000/preflight:alpha
docker push localhost:32000/troubleshoot:alpha
docker push localhost:32000/preflight:alpha
.PHONY: run-preflight
run-preflight: bin/preflight
./bin/preflight ./examples/preflight/sample-preflight.yaml
.PHONY: run-support-bundle
run-support-bundle: bin/support-bundle
./bin/support-bundle ./examples/support-bundle/sample-supportbundle.yaml
.PHONY: run-analyze
run-analyze: bin/analyze
./bin/analyze --analyzers ./examples/support-bundle/sample-analyzers.yaml ./support-bundle.tar.gz
.PHONY: init-sbom
init-sbom:
mkdir -p sbom/spdx sbom/assets
.PHONY: install-spdx-sbom-generator
install-spdx-sbom-generator: init-sbom
./scripts/initialize-sbom-build.sh
SPDX_GENERATOR=./sbom/spdx-sbom-generator
.PHONY: generate-sbom
generate-sbom: install-spdx-sbom-generator
$(SPDX_GENERATOR) -o ./sbom/spdx
sbom/assets/troubleshoot-sbom.tgz: generate-sbom
tar -czf sbom/assets/troubleshoot-sbom.tgz sbom/spdx/*.spdx
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
.PHONY: scan
scan:
trivy fs \
--scanners vuln \
--exit-code=1 \
--severity="HIGH,CRITICAL" \
--ignore-unfixed \
./
.PHONY: lint
lint:
golangci-lint run --new -c .golangci.yaml ${BUILDPATHS}
.PHONY: lint-and-fix
lint-and-fix:
golangci-lint run --new --fix -c .golangci.yaml ${BUILDPATHS}
.PHONY: watch
watch: npm-install
bin/watch.js
## Syncronize the code with a remote server. More info: CONTRIBUTING.md
.PHONY: watchrsync
watchrsync: npm-install
bin/watchrsync.js
.PHONY: 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
-29
View File
@@ -1,29 +0,0 @@
#!/usr/bin/env node
const gri = require('gaze-run-interrupt');
const commands = [
// {
// command: 'rm',
// args: binList,
// },
{
command: 'make',
args: ['build'],
},
];
commands.push({
command: "date",
args: [],
});
commands.push({
command: "echo",
args: ["synced"],
});
gri([
'cmd/**/*.go',
'pkg/**/*.go',
], commands);
-51
View File
@@ -1,51 +0,0 @@
#!/usr/bin/env node
const gri = require('gaze-run-interrupt');
if (!process.env.REMOTES) {
console.log("Usage: `REMOTES='user@h1.1.1.1,user@1.1.1.2' ./watchrsync.js`");
process.exit(1);
}
process.env.GOOS = 'linux';
process.env.GOARCH = 'amd64';
const binList = [
// 'bin/analyze',
// 'bin/preflight',
'bin/support-bundle',
// 'bin/collect'
]
const commands = [
// {
// command: 'rm',
// args: binList,
// },
{
command: 'make',
args: ['build'],
},
];
process.env.REMOTES.split(",").forEach(function (remote) {
commands.push({
command: 'rsync',
args: binList.concat(`${remote}:`),
});
});
commands.push({
command: "date",
args: [],
});
commands.push({
command: "echo",
args: ["synced"],
});
gri([
'cmd/**/*.go',
'pkg/**/*.go',
], commands);
+42 -2
View File
@@ -1,6 +1,7 @@
package cli
import (
"fmt"
"os"
"strings"
@@ -12,10 +13,26 @@ import (
"k8s.io/klog/v2"
)
// validateArgs allows certain flags to run without requiring bundle arguments
func validateArgs(cmd *cobra.Command, args []string) error {
// Special flags that don't require bundle arguments
if cmd.Flags().Changed("check-ollama") || cmd.Flags().Changed("setup-ollama") ||
cmd.Flags().Changed("list-models") || cmd.Flags().Changed("pull-model") {
return nil
}
// For all other cases, require at least 1 argument (the bundle path)
if len(args) < 1 {
return fmt.Errorf("requires at least 1 arg(s), only received %d. Usage: analyze [bundle-path] or use --check-ollama/--setup-ollama", len(args))
}
return nil
}
func RootCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "analyze [url]",
Args: cobra.MinimumNArgs(1),
Args: validateArgs,
Short: "Analyze a support bundle",
Long: `Run a series of analyzers on a support bundle archive`,
SilenceUsage: true,
@@ -32,7 +49,13 @@ func RootCmd() *cobra.Command {
RunE: func(cmd *cobra.Command, args []string) error {
v := viper.GetViper()
return runAnalyzers(v, args[0])
// Handle cases where no bundle argument is provided (for utility flags)
var bundlePath string
if len(args) > 0 {
bundlePath = args[0]
}
return runAnalyzers(v, bundlePath)
},
PostRun: func(cmd *cobra.Command, args []string) {
if err := util.StopProfiling(); err != nil {
@@ -48,6 +71,23 @@ func RootCmd() *cobra.Command {
cmd.Flags().String("analyzers", "", "filename or url of the analyzers to use")
cmd.Flags().Bool("debug", false, "enable debug logging")
// Advanced analysis flags
cmd.Flags().Bool("advanced-analysis", false, "use advanced analysis engine with AI capabilities")
cmd.Flags().StringSlice("agents", []string{"local"}, "analysis agents to use: local, hosted, ollama")
cmd.Flags().Bool("enable-ollama", false, "enable Ollama AI-powered analysis")
cmd.Flags().Bool("disable-ollama", false, "explicitly disable Ollama AI-powered analysis")
cmd.Flags().String("ollama-endpoint", "http://localhost:11434", "Ollama server endpoint")
cmd.Flags().String("ollama-model", "llama2:7b", "Ollama model to use for analysis")
cmd.Flags().Bool("use-codellama", false, "use CodeLlama model for code-focused analysis")
cmd.Flags().Bool("use-mistral", false, "use Mistral model for fast analysis")
cmd.Flags().Bool("auto-pull-model", true, "automatically pull model if not available")
cmd.Flags().Bool("list-models", false, "list all available/installed Ollama models and exit")
cmd.Flags().Bool("pull-model", false, "pull the specified model and exit")
cmd.Flags().Bool("setup-ollama", false, "automatically setup and configure Ollama")
cmd.Flags().Bool("check-ollama", false, "check Ollama installation status and exit")
cmd.Flags().Bool("include-remediation", true, "include remediation suggestions in analysis results")
cmd.Flags().String("output-file", "", "save analysis results to file (e.g., --output-file results.json)")
viper.BindPFlags(cmd.Flags())
viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
+689
View File
@@ -1,18 +1,408 @@
package cli
import (
"archive/tar"
"compress/gzip"
"context"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
"os/exec"
"path/filepath"
"strings"
"time"
"github.com/pkg/errors"
"github.com/replicatedhq/troubleshoot/internal/util"
analyzer "github.com/replicatedhq/troubleshoot/pkg/analyze"
"github.com/replicatedhq/troubleshoot/pkg/analyze/agents/local"
"github.com/replicatedhq/troubleshoot/pkg/analyze/agents/ollama"
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
"github.com/spf13/viper"
"k8s.io/klog/v2"
"sigs.k8s.io/yaml"
)
func runAnalyzers(v *viper.Viper, bundlePath string) error {
// Handle Ollama-specific commands first (these don't require a bundle)
if v.GetBool("setup-ollama") {
return handleOllamaSetup(v)
}
if v.GetBool("check-ollama") {
return handleOllamaStatus(v)
}
if v.GetBool("list-models") {
return handleListModels(v)
}
if v.GetBool("pull-model") {
return handlePullModel(v)
}
// For all other operations, we need a bundle path
if bundlePath == "" {
return errors.New("bundle path is required for analysis operations")
}
// Check if advanced analysis is requested
useAdvanced := v.GetBool("advanced-analysis") ||
v.GetBool("enable-ollama") ||
(len(v.GetStringSlice("agents")) > 1 ||
(len(v.GetStringSlice("agents")) == 1 && v.GetStringSlice("agents")[0] != "local"))
if useAdvanced {
return runAdvancedAnalysis(v, bundlePath)
}
// Only fall back to legacy analysis if no advanced flags are used at all
return runLegacyAnalysis(v, bundlePath)
}
// handleOllamaSetup automatically sets up Ollama for the user
func handleOllamaSetup(v *viper.Viper) error {
fmt.Println("🚀 Ollama Setup Assistant")
fmt.Println("=" + strings.Repeat("=", 50))
helper := analyzer.NewOllamaHelper()
// Check current status
status := helper.GetHealthStatus()
fmt.Print(status.String())
if !status.Installed {
fmt.Println("\n🔧 Installing Ollama...")
if err := helper.DownloadAndInstall(); err != nil {
return errors.Wrap(err, "failed to install Ollama")
}
fmt.Println("✅ Ollama installed successfully!")
}
if !status.Running {
fmt.Println("\n🚀 Starting Ollama service...")
if err := helper.StartService(); err != nil {
return errors.Wrap(err, "failed to start Ollama service")
}
fmt.Println("✅ Ollama service started!")
}
if len(status.Models) == 0 {
fmt.Println("\n📚 Downloading recommended model...")
helper.PrintModelRecommendations()
model := v.GetString("ollama-model")
if model == "" {
model = "llama2:7b"
}
fmt.Printf("\n⬇️ Pulling model: %s (this may take several minutes)...\n", model)
if err := helper.PullModel(model); err != nil {
return errors.Wrapf(err, "failed to pull model %s", model)
}
}
fmt.Println("\n🎉 Ollama setup complete!")
fmt.Println("\n💡 Next steps:")
fmt.Printf(" troubleshoot analyze --enable-ollama %s\n", filepath.Base(os.Args[len(os.Args)-1]))
return nil
}
// handleOllamaStatus shows current Ollama installation and service status
func handleOllamaStatus(v *viper.Viper) error {
helper := analyzer.NewOllamaHelper()
status := helper.GetHealthStatus()
fmt.Println("🔍 Ollama Status Report")
fmt.Println("=" + strings.Repeat("=", 50))
fmt.Print(status.String())
if !status.Installed {
fmt.Println("\n🔧 Setup Instructions:")
fmt.Println(helper.GetInstallInstructions())
return nil
}
if !status.Running {
fmt.Println("\n🚀 To start Ollama service:")
fmt.Println(" ollama serve &")
fmt.Println(" # or")
fmt.Println(" troubleshoot analyze --setup-ollama")
return nil
}
if len(status.Models) == 0 {
fmt.Println("\n📚 No models installed. Recommended models:")
helper.PrintModelRecommendations()
} else {
fmt.Println("\n✅ Ready for AI-powered analysis!")
fmt.Printf(" troubleshoot analyze --enable-ollama your-bundle.tar.gz\n")
}
return nil
}
// handleListModels lists available and installed Ollama models
func handleListModels(v *viper.Viper) error {
helper := analyzer.NewOllamaHelper()
status := helper.GetHealthStatus()
fmt.Println("🤖 Ollama Model Management")
fmt.Println("=" + strings.Repeat("=", 50))
if !status.Installed {
fmt.Println("❌ Ollama is not installed")
fmt.Println("💡 Install with: troubleshoot analyze --setup-ollama")
return nil
}
if !status.Running {
fmt.Println("⚠️ Ollama service is not running")
fmt.Println("🚀 Start with: ollama serve &")
return nil
}
// Show installed models
fmt.Println("📚 Installed Models:")
if len(status.Models) == 0 {
fmt.Println(" No models installed")
} else {
for _, model := range status.Models {
fmt.Printf(" ✅ %s\n", model)
}
}
// Show available models for download
fmt.Println("\n🌐 Available Models:")
helper.PrintModelRecommendations()
// Show usage examples
fmt.Println("💡 Usage Examples:")
fmt.Println(" # Use specific model:")
fmt.Printf(" troubleshoot analyze --ollama-model llama2:13b bundle.tar.gz\n")
fmt.Println(" # Use preset models:")
fmt.Printf(" troubleshoot analyze --use-codellama bundle.tar.gz\n")
fmt.Printf(" troubleshoot analyze --use-mistral bundle.tar.gz\n")
fmt.Println(" # Pull a new model:")
fmt.Printf(" troubleshoot analyze --ollama-model llama2:13b --pull-model\n")
return nil
}
// handlePullModel pulls a specific model
func handlePullModel(v *viper.Viper) error {
helper := analyzer.NewOllamaHelper()
status := helper.GetHealthStatus()
if !status.Installed {
fmt.Println("❌ Ollama is not installed")
fmt.Println("💡 Install with: troubleshoot analyze --setup-ollama")
return errors.New("Ollama must be installed to pull models")
}
if !status.Running {
fmt.Println("❌ Ollama service is not running")
fmt.Println("🚀 Start with: ollama serve &")
return errors.New("Ollama service must be running to pull models")
}
// Determine which model to pull
model := determineOllamaModel(v)
fmt.Printf("📥 Pulling model: %s\n", model)
fmt.Println("=" + strings.Repeat("=", 50))
if err := helper.PullModel(model); err != nil {
return errors.Wrapf(err, "failed to pull model %s", model)
}
fmt.Printf("\n✅ Model %s ready for analysis!\n", model)
fmt.Println("\n💡 Test it with:")
fmt.Printf(" troubleshoot analyze --ollama-model %s bundle.tar.gz\n", model)
return nil
}
// runAdvancedAnalysis uses the new analysis engine with agent support
func runAdvancedAnalysis(v *viper.Viper, bundlePath string) error {
ctx := context.Background()
// Create the analysis engine
engine := analyzer.NewAnalysisEngine()
// Determine which agents to use
agents := v.GetStringSlice("agents")
// Handle Ollama flags
enableOllama := v.GetBool("enable-ollama")
disableOllama := v.GetBool("disable-ollama")
if enableOllama && !disableOllama {
// Add ollama to agents if not already present
hasOllama := false
for _, agent := range agents {
if agent == "ollama" {
hasOllama = true
break
}
}
if !hasOllama {
agents = append(agents, "ollama")
}
}
if disableOllama {
// Remove ollama from agents
filteredAgents := []string{}
for _, agent := range agents {
if agent != "ollama" {
filteredAgents = append(filteredAgents, agent)
}
}
agents = filteredAgents
}
// Register requested agents
registeredAgents := []string{}
for _, agentName := range agents {
switch agentName {
case "ollama":
if err := registerOllamaAgent(engine, v); err != nil {
return err
}
registeredAgents = append(registeredAgents, agentName)
case "local":
opts := &local.LocalAgentOptions{}
agent := local.NewLocalAgent(opts)
if err := engine.RegisterAgent("local", agent); err != nil {
return errors.Wrap(err, "failed to register local agent")
}
registeredAgents = append(registeredAgents, agentName)
default:
klog.Warningf("Unknown agent type: %s", agentName)
}
}
if len(registeredAgents) == 0 {
return errors.New("no analysis agents available - check your configuration")
}
fmt.Printf("🔍 Using analysis agents: %s\n", strings.Join(registeredAgents, ", "))
// Load support bundle
bundle, err := loadSupportBundle(bundlePath)
if err != nil {
return errors.Wrap(err, "failed to load support bundle")
}
// Load analyzer specs if provided
var customAnalyzers []*troubleshootv1beta2.Analyze
if specPath := v.GetString("analyzers"); specPath != "" {
customAnalyzers, err = loadAnalyzerSpecs(specPath)
if err != nil {
return errors.Wrap(err, "failed to load analyzer specs")
}
}
// Configure analysis options
opts := analyzer.AnalysisOptions{
Agents: registeredAgents,
IncludeRemediation: v.GetBool("include-remediation"),
CustomAnalyzers: customAnalyzers,
Timeout: 5 * time.Minute,
Concurrency: 2,
}
// Run analysis
fmt.Printf("🚀 Starting advanced analysis of bundle: %s\n", bundlePath)
result, err := engine.Analyze(ctx, bundle, opts)
if err != nil {
return errors.Wrap(err, "analysis failed")
}
// Display results
return displayAdvancedResults(result, v.GetString("output"), v.GetString("output-file"))
}
// registerOllamaAgent creates and registers an Ollama agent
func registerOllamaAgent(engine analyzer.AnalysisEngine, v *viper.Viper) error {
// Check if Ollama is available
helper := analyzer.NewOllamaHelper()
status := helper.GetHealthStatus()
if !status.Installed {
return showOllamaSetupHelp("Ollama is not installed")
}
if !status.Running {
return showOllamaSetupHelp("Ollama service is not running")
}
if len(status.Models) == 0 {
return showOllamaSetupHelp("No Ollama models are installed")
}
// Determine which model to use
selectedModel := determineOllamaModel(v)
// Auto-pull model if requested and not available
if v.GetBool("auto-pull-model") {
if err := ensureModelAvailable(selectedModel); err != nil {
return errors.Wrapf(err, "failed to ensure model %s is available", selectedModel)
}
}
// Create Ollama agent
opts := &ollama.OllamaAgentOptions{
Endpoint: v.GetString("ollama-endpoint"),
Model: selectedModel,
Timeout: 5 * time.Minute,
MaxTokens: 2000,
Temperature: 0.2,
}
agent, err := ollama.NewOllamaAgent(opts)
if err != nil {
return errors.Wrap(err, "failed to create Ollama agent")
}
// Register with engine
if err := engine.RegisterAgent("ollama", agent); err != nil {
return errors.Wrap(err, "failed to register Ollama agent")
}
return nil
}
// showOllamaSetupHelp displays helpful setup instructions when Ollama is not available
func showOllamaSetupHelp(reason string) error {
fmt.Printf("❌ Ollama AI analysis not available: %s\n\n", reason)
helper := analyzer.NewOllamaHelper()
fmt.Println("🔧 Quick Setup:")
fmt.Println(" troubleshoot analyze --setup-ollama")
fmt.Println()
fmt.Println("📋 Manual Setup:")
fmt.Println(" 1. Install: curl -fsSL https://ollama.ai/install.sh | sh")
fmt.Println(" 2. Start service: ollama serve &")
fmt.Println(" 3. Pull model: ollama pull llama2:7b")
fmt.Println(" 4. Retry analysis with: --enable-ollama")
fmt.Println()
fmt.Println("💡 Check status: troubleshoot analyze --check-ollama")
fmt.Println()
fmt.Println(helper.GetInstallInstructions())
return errors.New("Ollama setup required for AI-powered analysis")
}
// runLegacyAnalysis runs the original analysis logic for backward compatibility
func runLegacyAnalysis(v *viper.Viper, bundlePath string) error {
specPath := v.GetString("analyzers")
specContent := ""
@@ -66,3 +456,302 @@ func runAnalyzers(v *viper.Viper, bundlePath string) error {
return nil
}
// loadSupportBundle loads and parses a support bundle from file
func loadSupportBundle(bundlePath string) (*analyzer.SupportBundle, error) {
if _, err := os.Stat(bundlePath); os.IsNotExist(err) {
return nil, errors.Errorf("support bundle not found: %s", bundlePath)
}
klog.Infof("Loading support bundle: %s", bundlePath)
// Open the tar.gz file
file, err := os.Open(bundlePath)
if err != nil {
return nil, errors.Wrap(err, "failed to open support bundle")
}
defer file.Close()
// Create gzip reader
gzipReader, err := gzip.NewReader(file)
if err != nil {
return nil, errors.Wrap(err, "failed to create gzip reader")
}
defer gzipReader.Close()
// Create tar reader
tarReader := tar.NewReader(gzipReader)
// Create bundle structure
bundle := &analyzer.SupportBundle{
Files: make(map[string][]byte),
Metadata: &analyzer.SupportBundleMetadata{
CreatedAt: time.Now(),
Version: "1.0.0",
GeneratedBy: "troubleshoot-cli",
},
}
// Extract all files from tar
for {
header, err := tarReader.Next()
if err == io.EOF {
break
}
if err != nil {
return nil, errors.Wrap(err, "failed to read tar entry")
}
// Skip directories
if header.Typeflag == tar.TypeDir {
continue
}
// Read file content
content, err := io.ReadAll(tarReader)
if err != nil {
return nil, errors.Wrapf(err, "failed to read file %s", header.Name)
}
// Remove bundle directory prefix from file path for consistent access
// e.g., "live-cluster-bundle/cluster-info/version.json" → "cluster-info/version.json"
cleanPath := header.Name
if parts := strings.SplitN(header.Name, "/", 2); len(parts) == 2 {
cleanPath = parts[1]
}
bundle.Files[cleanPath] = content
klog.V(2).Infof("Loaded file: %s (%d bytes)", cleanPath, len(content))
}
klog.Infof("Successfully loaded support bundle with %d files", len(bundle.Files))
return bundle, nil
}
// loadAnalyzerSpecs loads analyzer specifications from file or URL
func loadAnalyzerSpecs(specPath string) ([]*troubleshootv1beta2.Analyze, error) {
klog.Infof("Loading analyzer specs from: %s", specPath)
// Read the analyzer spec file (same logic as runLegacyAnalysis)
specContent := ""
var err error
if _, err = os.Stat(specPath); err == nil {
b, err := os.ReadFile(specPath)
if err != nil {
return nil, errors.Wrap(err, "failed to read analyzer spec file")
}
specContent = string(b)
} else {
if !util.IsURL(specPath) {
return nil, errors.Errorf("analyzer spec %s is not a URL and was not found", specPath)
}
req, err := http.NewRequest("GET", specPath, nil)
if err != nil {
return nil, errors.Wrap(err, "failed to create HTTP request")
}
req.Header.Set("User-Agent", "Replicated_Analyzer/v1beta2")
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, errors.Wrap(err, "failed to fetch analyzer spec")
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, errors.Wrap(err, "failed to read analyzer spec response")
}
specContent = string(body)
}
// Parse the YAML/JSON into troubleshoot analyzer struct
var analyzerSpec troubleshootv1beta2.Analyzer
if err := yaml.Unmarshal([]byte(specContent), &analyzerSpec); err != nil {
return nil, errors.Wrap(err, "failed to parse analyzer spec")
}
// Return the analyzer specs from the parsed document
return analyzerSpec.Spec.Analyzers, nil
}
// displayAdvancedResults formats and displays analysis results
func displayAdvancedResults(result *analyzer.AnalysisResult, outputFormat, outputFile string) error {
if result == nil {
return errors.New("no analysis results to display")
}
// Display summary
fmt.Println("\n📊 Analysis Summary")
fmt.Println("=" + strings.Repeat("=", 50))
fmt.Printf("Total Analyzers: %d\n", result.Summary.TotalAnalyzers)
fmt.Printf("✅ Pass: %d\n", result.Summary.PassCount)
fmt.Printf("⚠️ Warn: %d\n", result.Summary.WarnCount)
fmt.Printf("❌ Fail: %d\n", result.Summary.FailCount)
fmt.Printf("🚫 Errors: %d\n", result.Summary.ErrorCount)
fmt.Printf("⏱️ Duration: %s\n", result.Summary.Duration)
fmt.Printf("🤖 Agents Used: %s\n", strings.Join(result.Summary.AgentsUsed, ", "))
if result.Summary.Confidence > 0 {
fmt.Printf("🎯 Confidence: %.1f%%\n", result.Summary.Confidence*100)
}
// Display results based on format
switch outputFormat {
case "json":
jsonData, err := json.MarshalIndent(result, "", " ")
if err != nil {
return errors.Wrap(err, "failed to marshal results to JSON")
}
fmt.Println("\n📄 Full Results (JSON):")
fmt.Println(string(jsonData))
default:
// Human-readable format
fmt.Println("\n🔍 Analysis Results")
fmt.Println("=" + strings.Repeat("=", 50))
for _, analyzerResult := range result.Results {
status := "❓"
if analyzerResult.IsPass {
status = "✅"
} else if analyzerResult.IsWarn {
status = "⚠️"
} else if analyzerResult.IsFail {
status = "❌"
}
fmt.Printf("\n%s %s", status, analyzerResult.Title)
if analyzerResult.AgentName != "" {
fmt.Printf(" [%s]", analyzerResult.AgentName)
}
if analyzerResult.Confidence > 0 {
fmt.Printf(" (%.0f%% confidence)", analyzerResult.Confidence*100)
}
fmt.Println()
if analyzerResult.Message != "" {
fmt.Printf(" %s\n", analyzerResult.Message)
}
if analyzerResult.Category != "" {
fmt.Printf(" Category: %s\n", analyzerResult.Category)
}
// Display insights if available
if len(analyzerResult.Insights) > 0 {
fmt.Println(" 💡 Insights:")
for _, insight := range analyzerResult.Insights {
fmt.Printf(" • %s\n", insight)
}
}
// Display remediation if available
if analyzerResult.Remediation != nil {
fmt.Printf(" 🔧 Remediation: %s\n", analyzerResult.Remediation.Description)
if analyzerResult.Remediation.Command != "" {
fmt.Printf(" 💻 Command: %s\n", analyzerResult.Remediation.Command)
}
}
}
// Display overall remediation suggestions
if len(result.Remediation) > 0 {
fmt.Println("\n🔧 Recommended Actions")
fmt.Println("=" + strings.Repeat("=", 50))
for i, remedy := range result.Remediation {
fmt.Printf("%d. %s\n", i+1, remedy.Description)
if remedy.Command != "" {
fmt.Printf(" Command: %s\n", remedy.Command)
}
if remedy.Documentation != "" {
fmt.Printf(" Docs: %s\n", remedy.Documentation)
}
}
}
// Display errors if any
if len(result.Errors) > 0 {
fmt.Println("\n⚠️ Errors During Analysis")
fmt.Println("=" + strings.Repeat("=", 30))
for _, analysisError := range result.Errors {
fmt.Printf("• [%s] %s: %s\n", analysisError.Agent, analysisError.Category, analysisError.Error)
}
}
// Display agent metadata
if len(result.Metadata.Agents) > 0 {
fmt.Println("\n🤖 Agent Performance")
fmt.Println("=" + strings.Repeat("=", 40))
for _, agent := range result.Metadata.Agents {
fmt.Printf("• %s: %d results, %s duration", agent.Name, agent.ResultCount, agent.Duration)
if agent.ErrorCount > 0 {
fmt.Printf(" (%d errors)", agent.ErrorCount)
}
fmt.Println()
}
}
}
// Save results to file if requested
if outputFile != "" {
jsonData, err := json.MarshalIndent(result, "", " ")
if err != nil {
return errors.Wrap(err, "failed to marshal results for file output")
}
if err := os.WriteFile(outputFile, jsonData, 0644); err != nil {
return errors.Wrapf(err, "failed to write results to %s", outputFile)
}
fmt.Printf("\n💾 Analysis results saved to: %s\n", outputFile)
}
return nil
}
// determineOllamaModel selects the appropriate model based on flags
func determineOllamaModel(v *viper.Viper) string {
// Check for specific model flags first
if v.GetBool("use-codellama") {
return "codellama:7b"
}
if v.GetBool("use-mistral") {
return "mistral:7b"
}
// Fall back to explicit model specification or default
return v.GetString("ollama-model")
}
// ensureModelAvailable checks if model exists and pulls it if needed
func ensureModelAvailable(model string) error {
// Check if model is already available
cmd := exec.Command("ollama", "list")
output, err := cmd.Output()
if err != nil {
return errors.Wrap(err, "failed to check available models")
}
// Parse model list to see if our model exists
lines := strings.Split(string(output), "\n")
for _, line := range lines {
if strings.Contains(line, model) {
klog.Infof("Model %s is already available", model)
return nil
}
}
// Model not found, pull it
fmt.Printf("📚 Model %s not found, pulling automatically...\n", model)
pullCmd := exec.Command("ollama", "pull", model)
pullCmd.Stdout = os.Stdout
pullCmd.Stderr = os.Stderr
if err := pullCmd.Run(); err != nil {
return errors.Wrapf(err, "failed to pull model %s", model)
}
fmt.Printf("✅ Model %s pulled successfully!\n", model)
return nil
}
-10
View File
@@ -1,10 +0,0 @@
package main
import (
"github.com/replicatedhq/troubleshoot/cmd/analyze/cli"
_ "k8s.io/client-go/plugin/pkg/client/auth"
)
func main() {
cli.InitAndExecute()
}
-85
View File
@@ -1,85 +0,0 @@
package cli
import (
"os"
"strings"
"github.com/replicatedhq/troubleshoot/cmd/internal/util"
"github.com/replicatedhq/troubleshoot/pkg/k8sutil"
"github.com/replicatedhq/troubleshoot/pkg/logger"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"k8s.io/klog/v2"
)
func RootCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "collect [url]",
Args: cobra.MinimumNArgs(1),
Short: "Run a collector",
Long: `Run a collector and output the results.`,
SilenceUsage: true,
PreRun: func(cmd *cobra.Command, args []string) {
v := viper.GetViper()
v.BindPFlags(cmd.Flags())
logger.SetupLogger(v)
if err := util.StartProfiling(); err != nil {
klog.Errorf("Failed to start profiling: %v", err)
}
},
RunE: func(cmd *cobra.Command, args []string) error {
v := viper.GetViper()
return runCollect(v, args[0])
},
PostRun: func(cmd *cobra.Command, args []string) {
if err := util.StopProfiling(); err != nil {
klog.Errorf("Failed to stop profiling: %v", err)
}
},
}
cobra.OnInitialize(initConfig)
cmd.AddCommand(util.VersionCmd())
cmd.Flags().StringSlice("redactors", []string{}, "names of the additional redactors to use")
cmd.Flags().Bool("redact", true, "enable/disable default redactions")
cmd.Flags().String("format", "json", "output format, one of json or raw.")
cmd.Flags().String("collector-image", "", "the full name of the collector image to use")
cmd.Flags().String("collector-pull-policy", "", "the pull policy of the collector image")
cmd.Flags().String("selector", "", "selector (label query) to filter remote collection nodes on.")
cmd.Flags().Bool("collect-without-permissions", false, "always generate a support bundle, even if it some require additional permissions")
cmd.Flags().Bool("debug", false, "enable debug logging")
// hidden in favor of the `insecure-skip-tls-verify` flag
cmd.Flags().Bool("allow-insecure-connections", false, "when set, do not verify TLS certs when retrieving spec and reporting results")
cmd.Flags().MarkHidden("allow-insecure-connections")
viper.BindPFlags(cmd.Flags())
viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
k8sutil.AddFlags(cmd.Flags())
// Initialize klog flags
logger.InitKlogFlags(cmd)
// CPU and memory profiling flags
util.AddProfilingFlags(cmd)
return cmd
}
func InitAndExecute() {
if err := RootCmd().Execute(); err != nil {
os.Exit(1)
}
}
func initConfig() {
viper.SetEnvPrefix("TROUBLESHOOT")
viper.AutomaticEnv()
}
-181
View File
@@ -1,181 +0,0 @@
package cli
import (
"fmt"
"io/ioutil"
"net/http"
"os"
"os/signal"
"strings"
"time"
"github.com/pkg/errors"
"github.com/replicatedhq/troubleshoot/internal/util"
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
"github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/scheme"
"github.com/replicatedhq/troubleshoot/pkg/collect"
"github.com/replicatedhq/troubleshoot/pkg/docrewrite"
"github.com/replicatedhq/troubleshoot/pkg/k8sutil"
"github.com/replicatedhq/troubleshoot/pkg/specs"
"github.com/replicatedhq/troubleshoot/pkg/supportbundle"
"github.com/spf13/viper"
"k8s.io/apimachinery/pkg/labels"
)
const (
defaultTimeout = 30 * time.Second
)
func runCollect(v *viper.Viper, arg string) error {
go func() {
signalChan := make(chan os.Signal, 1)
signal.Notify(signalChan, os.Interrupt)
<-signalChan
os.Exit(0)
}()
var collectorContent []byte
var err error
if strings.HasPrefix(arg, "secret/") {
// format secret/namespace-name/secret-name
pathParts := strings.Split(arg, "/")
if len(pathParts) != 3 {
return errors.Errorf("path %s must have 3 components", arg)
}
spec, err := specs.LoadFromSecret(pathParts[1], pathParts[2], "collect-spec")
if err != nil {
return errors.Wrap(err, "failed to get spec from secret")
}
collectorContent = spec
} else if _, err = os.Stat(arg); err == nil {
b, err := os.ReadFile(arg)
if err != nil {
return err
}
collectorContent = b
} else {
if !util.IsURL(arg) {
return fmt.Errorf("%s is not a URL and was not found", arg)
}
req, err := http.NewRequest("GET", arg, nil)
if err != nil {
return err
}
req.Header.Set("User-Agent", "Replicated_Collect/v1beta2")
resp, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
collectorContent = body
}
collectorContent, err = docrewrite.ConvertToV1Beta2(collectorContent)
if err != nil {
return errors.Wrap(err, "failed to convert to v1beta2")
}
multidocs := strings.Split(string(collectorContent), "\n---\n")
decode := scheme.Codecs.UniversalDeserializer().Decode
redactors, err := supportbundle.GetRedactorsFromURIs(v.GetStringSlice("redactors"))
if err != nil {
return errors.Wrap(err, "failed to get redactors")
}
additionalRedactors := &troubleshootv1beta2.Redactor{
Spec: troubleshootv1beta2.RedactorSpec{
Redactors: redactors,
},
}
for i, additionalDoc := range multidocs {
if i == 0 {
continue
}
additionalDoc, err := docrewrite.ConvertToV1Beta2([]byte(additionalDoc))
if err != nil {
return errors.Wrap(err, "failed to convert to v1beta2")
}
obj, _, err := decode(additionalDoc, nil, nil)
if err != nil {
return errors.Wrapf(err, "failed to parse additional doc %d", i)
}
multidocRedactors, ok := obj.(*troubleshootv1beta2.Redactor)
if !ok {
continue
}
additionalRedactors.Spec.Redactors = append(additionalRedactors.Spec.Redactors, multidocRedactors.Spec.Redactors...)
}
// make sure we don't block any senders
progressCh := make(chan interface{})
defer close(progressCh)
go func() {
for range progressCh {
}
}()
restConfig, err := k8sutil.GetRESTConfig()
if err != nil {
return errors.Wrap(err, "failed to convert kube flags to rest config")
}
labelSelector, err := labels.Parse(v.GetString("selector"))
if err != nil {
return errors.Wrap(err, "unable to parse selector")
}
namespace := v.GetString("namespace")
if namespace == "" {
namespace = "default"
}
timeout := v.GetDuration("request-timeout")
if timeout == 0 {
timeout = defaultTimeout
}
createOpts := collect.CollectorRunOpts{
CollectWithoutPermissions: v.GetBool("collect-without-permissions"),
KubernetesRestConfig: restConfig,
Image: v.GetString("collector-image"),
PullPolicy: v.GetString("collector-pullpolicy"),
LabelSelector: labelSelector.String(),
Namespace: namespace,
Timeout: timeout,
ProgressChan: progressCh,
}
// we only support HostCollector or RemoteCollector kinds.
hostCollector, err := collect.ParseHostCollectorFromDoc([]byte(multidocs[0]))
if err == nil {
results, err := collect.CollectHost(hostCollector, additionalRedactors, createOpts)
if err != nil {
return errors.Wrap(err, "failed to collect from host")
}
return showHostStdoutResults(v.GetString("format"), hostCollector.Name, results)
}
remoteCollector, err := collect.ParseRemoteCollectorFromDoc([]byte(multidocs[0]))
if err == nil {
results, err := collect.CollectRemote(remoteCollector, additionalRedactors, createOpts)
if err != nil {
return errors.Wrap(err, "failed to collect from remote host(s)")
}
return showRemoteStdoutResults(v.GetString("format"), remoteCollector.Name, results)
}
return errors.New("failed to parse hostCollector or remoteCollector")
}
-103
View File
@@ -1,103 +0,0 @@
package cli
import (
"encoding/json"
"fmt"
"github.com/pkg/errors"
"github.com/replicatedhq/troubleshoot/pkg/collect"
)
const (
// FormatJSON is intended for CLI output.
FormatJSON = "json"
// FormatRaw is intended for consumption by a remote collector. Output is a
// string of quoted JSON.
FormatRaw = "raw"
)
func showHostStdoutResults(format string, collectName string, results *collect.HostCollectResult) error {
switch format {
case FormatJSON:
return showHostStdoutResultsJSON(collectName, results.AllCollectedData)
case FormatRaw:
return showHostStdoutResultsRaw(collectName, results.AllCollectedData)
default:
return errors.Errorf("unknown output format: %q", format)
}
}
func showRemoteStdoutResults(format string, collectName string, results *collect.RemoteCollectResult) error {
switch format {
case FormatJSON:
return showRemoteStdoutResultsJSON(collectName, results.AllCollectedData)
case FormatRaw:
return errors.Errorf("raw format not supported for remote collectors")
default:
return errors.Errorf("unknown output format: %q", format)
}
}
func showHostStdoutResultsJSON(collectName string, results map[string][]byte) error {
output := make(map[string]interface{})
for file, collectorResult := range results {
var collectedItems map[string]interface{}
if err := json.Unmarshal([]byte(collectorResult), &collectedItems); err != nil {
return errors.Wrap(err, "failed to marshal collector results")
}
output[file] = collectedItems
}
formatted, err := json.MarshalIndent(output, "", " ")
if err != nil {
return errors.Wrap(err, "failed to convert output to json")
}
fmt.Print(string(formatted))
return nil
}
// showHostStdoutResultsRaw outputs the collector output as a string of quoted json.
func showHostStdoutResultsRaw(collectName string, results map[string][]byte) error {
strData := map[string]string{}
for k, v := range results {
strData[k] = string(v)
}
formatted, err := json.MarshalIndent(strData, "", " ")
if err != nil {
return errors.Wrap(err, "failed to convert output to json")
}
fmt.Print(string(formatted))
return nil
}
func showRemoteStdoutResultsJSON(collectName string, results map[string][]byte) error {
type CollectorResult map[string]interface{}
type NodeResult map[string]CollectorResult
var output = make(map[string]NodeResult)
for node, result := range results {
var nodeResult map[string]string
if err := json.Unmarshal(result, &nodeResult); err != nil {
return errors.Wrap(err, "failed to marshal node results")
}
nr := make(NodeResult)
for file, collectorResult := range nodeResult {
var collectedItems map[string]interface{}
if err := json.Unmarshal([]byte(collectorResult), &collectedItems); err != nil {
return errors.Wrap(err, "failed to marshal collector results")
}
nr[file] = collectedItems
}
output[node] = nr
}
formatted, err := json.MarshalIndent(output, "", " ")
if err != nil {
return errors.Wrap(err, "failed to convert output to json")
}
fmt.Print(string(formatted))
return nil
}
-10
View File
@@ -1,10 +0,0 @@
package main
import (
"github.com/replicatedhq/troubleshoot/cmd/collect/cli"
_ "k8s.io/client-go/plugin/pkg/client/auth"
)
func main() {
cli.InitAndExecute()
}
-37
View File
@@ -1,37 +0,0 @@
package cli
import (
"log"
"os"
preflightcli "github.com/replicatedhq/troubleshoot/cmd/preflight/cli"
troubleshootcli "github.com/replicatedhq/troubleshoot/cmd/troubleshoot/cli"
"github.com/spf13/cobra"
"github.com/spf13/cobra/doc"
)
func RootCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "docsgen",
Short: "Generate markdown docs for the commands in this project",
}
preflight := preflightcli.RootCmd()
troubleshoot := troubleshootcli.RootCmd()
commands := []*cobra.Command{preflight, troubleshoot}
for _, command := range commands {
err := doc.GenMarkdownTree(command, "./docs")
if err != nil {
log.Fatal(err)
}
}
return cmd
}
func InitAndExecute() {
if err := RootCmd().Execute(); err != nil {
os.Exit(1)
}
}
-10
View File
@@ -1,10 +0,0 @@
package main
import (
"github.com/replicatedhq/troubleshoot/cmd/docsgen/cli"
_ "k8s.io/client-go/plugin/pkg/client/auth"
)
func main() {
cli.InitAndExecute()
}
+132
View File
@@ -0,0 +1,132 @@
package cli
import (
"fmt"
"io/ioutil"
"path/filepath"
"strings"
"github.com/pkg/errors"
"github.com/replicatedhq/troubleshoot/pkg/convert"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
func ConvertCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "convert [input-file]",
Args: cobra.ExactArgs(1),
Short: "Convert v1beta2 preflight specs to v1beta3 format",
Long: `Convert v1beta2 preflight specs to v1beta3 format with templating and values.
This command converts a v1beta2 preflight spec to the new v1beta3 templated format. It will:
- Update the apiVersion to troubleshoot.sh/v1beta3
- Extract hardcoded values and create a values.yaml file
- Add conditional templating ({{- if .Values.feature.enabled }})
- Add placeholder docString comments for you to fill in
- Template hardcoded values with {{ .Values.* }} expressions
The conversion will create two files:
- [input-file]-v1beta3.yaml: The templated v1beta3 spec
- [input-file]-values.yaml: The values file with extracted configuration
Example:
preflight convert my-preflight.yaml
This creates:
my-preflight-v1beta3.yaml
my-preflight-values.yaml`,
PreRun: func(cmd *cobra.Command, args []string) {
viper.BindPFlags(cmd.Flags())
},
RunE: func(cmd *cobra.Command, args []string) error {
v := viper.GetViper()
inputFile := args[0]
outputSpec := v.GetString("output-spec")
outputValues := v.GetString("output-values")
// Generate default output filenames if not specified
if outputSpec == "" {
ext := filepath.Ext(inputFile)
base := strings.TrimSuffix(inputFile, ext)
outputSpec = base + "-v1beta3" + ext
}
if outputValues == "" {
ext := filepath.Ext(inputFile)
base := strings.TrimSuffix(inputFile, ext)
outputValues = base + "-values" + ext
}
return runConvert(v, inputFile, outputSpec, outputValues)
},
}
cmd.Flags().String("output-spec", "", "Output file for the templated v1beta3 spec (default: [input]-v1beta3.yaml)")
cmd.Flags().String("output-values", "", "Output file for the values (default: [input]-values.yaml)")
cmd.Flags().Bool("dry-run", false, "Preview the conversion without writing files")
return cmd
}
func runConvert(v *viper.Viper, inputFile, outputSpec, outputValues string) error {
// Read input file
inputData, err := ioutil.ReadFile(inputFile)
if err != nil {
return errors.Wrapf(err, "failed to read input file %s", inputFile)
}
// Check if it's a valid v1beta2 preflight spec
if !strings.Contains(string(inputData), "troubleshoot.sh/v1beta2") {
return fmt.Errorf("input file does not appear to be a v1beta2 troubleshoot spec")
}
if !strings.Contains(string(inputData), "kind: Preflight") {
return fmt.Errorf("input file does not appear to be a Preflight spec")
}
// Convert to v1beta3
result, err := convert.ConvertToV1Beta3(inputData)
if err != nil {
return errors.Wrap(err, "failed to convert spec")
}
dryRun := v.GetBool("dry-run")
if dryRun {
fmt.Println("=== Templated v1beta3 Spec ===")
fmt.Println(result.TemplatedSpec)
fmt.Println("\n=== Values File ===")
fmt.Println(result.ValuesFile)
fmt.Println("\n=== Conversion Summary ===")
fmt.Printf("Would write templated spec to: %s\n", outputSpec)
fmt.Printf("Would write values to: %s\n", outputValues)
return nil
}
// Write templated spec
err = ioutil.WriteFile(outputSpec, []byte(result.TemplatedSpec), 0644)
if err != nil {
return errors.Wrapf(err, "failed to write templated spec to %s", outputSpec)
}
// Write values file
err = ioutil.WriteFile(outputValues, []byte(result.ValuesFile), 0644)
if err != nil {
return errors.Wrapf(err, "failed to write values to %s", outputValues)
}
fmt.Printf("Successfully converted %s to v1beta3 format:\n", inputFile)
fmt.Printf(" Templated spec: %s\n", outputSpec)
fmt.Printf(" Values file: %s\n", outputValues)
fmt.Println("\nNext steps:")
fmt.Println("1. Add docStrings with Title, Requirement, and rationale for each check")
fmt.Println("2. Customize the values in the values file")
fmt.Println("3. Test the conversion with:")
fmt.Printf(" preflight template %s --values %s\n", outputSpec, outputValues)
fmt.Println("4. Run the templated preflight:")
fmt.Printf(" preflight run %s --values %s\n", outputSpec, outputValues)
return nil
}
+387
View File
@@ -0,0 +1,387 @@
package cli
import (
"bytes"
"fmt"
"os"
"strings"
"text/template"
"github.com/Masterminds/sprig/v3"
"github.com/pkg/errors"
"github.com/replicatedhq/troubleshoot/pkg/preflight"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"gopkg.in/yaml.v2"
"helm.sh/helm/v3/pkg/strvals"
)
func DocsCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "docs [preflight-file...]",
Short: "Extract and display documentation from a preflight spec",
Long: `Extract all docString fields from enabled requirements in one or more preflight YAML files.
This command processes templated preflight specs, evaluates conditionals, and outputs
only the documentation for requirements that would be included based on the provided values.
Examples:
# Extract docs with default values
preflight docs ml-platform-preflight.yaml
# Extract docs from multiple specs with values from files
preflight docs spec1.yaml spec2.yaml --values base-values.yaml --values prod-values.yaml
# Extract docs with inline values
preflight docs ml-platform-preflight.yaml --set jupyter.enabled=true --set monitoring.enabled=false
# Extract docs and save to file
preflight docs ml-platform-preflight.yaml --output requirements.md`,
Args: cobra.MinimumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
v := viper.GetViper()
templateFiles := args
valuesFiles := v.GetStringSlice("values")
outputFile := v.GetString("output")
setValues := v.GetStringSlice("set")
return extractDocs(templateFiles, valuesFiles, setValues, outputFile)
},
}
cmd.Flags().StringSlice("values", []string{}, "Path to YAML files containing template values (can be used multiple times)")
cmd.Flags().StringSlice("set", []string{}, "Set template values on the command line (can be used multiple times)")
cmd.Flags().StringP("output", "o", "", "Output file (default: stdout)")
// Bind flags to viper
viper.BindPFlag("values", cmd.Flags().Lookup("values"))
viper.BindPFlag("set", cmd.Flags().Lookup("set"))
viper.BindPFlag("output", cmd.Flags().Lookup("output"))
return cmd
}
// PreflightDoc supports both legacy (requirements) and beta3 (spec.analyzers)
type PreflightDoc struct {
APIVersion string `yaml:"apiVersion"`
Kind string `yaml:"kind"`
Metadata map[string]interface{} `yaml:"metadata"`
Spec struct {
Analyzers []map[string]interface{} `yaml:"analyzers"`
} `yaml:"spec"`
// Legacy (pre-beta3 drafts)
Requirements []Requirement `yaml:"requirements"`
}
type Requirement struct {
Name string `yaml:"name"`
DocString string `yaml:"docString"`
Checks []map[string]interface{} `yaml:"checks,omitempty"`
}
func extractDocs(templateFiles []string, valuesFiles []string, setValues []string, outputFile string) error {
// Prepare the values map (merge all files, then apply sets)
values := make(map[string]interface{})
for _, valuesFile := range valuesFiles {
fileValues, err := loadValuesFile(valuesFile)
if err != nil {
return errors.Wrapf(err, "failed to load values file %s", valuesFile)
}
values = mergeMaps(values, fileValues)
}
// Normalize maps for Helm set merging
values = normalizeStringMaps(values)
for _, setValue := range setValues {
if err := applySetValue(values, setValue); err != nil {
return errors.Wrapf(err, "failed to apply set value: %s", setValue)
}
}
var combinedDocs strings.Builder
for _, templateFile := range templateFiles {
templateContent, err := os.ReadFile(templateFile)
if err != nil {
return errors.Wrapf(err, "failed to read template file %s", templateFile)
}
useHelm := shouldUseHelmEngine(string(templateContent))
var rendered string
if useHelm {
// Seed default-false for referenced boolean values to avoid nil map errors
preflight.SeedDefaultBooleans(string(templateContent), values)
rendered, err = preflight.RenderWithHelmTemplate(string(templateContent), values)
if err != nil {
execValues := legacyContext(values)
rendered, err = renderTemplate(string(templateContent), execValues)
if err != nil {
return errors.Wrap(err, "failed to render template (helm fallback also failed)")
}
}
} else {
execValues := legacyContext(values)
rendered, err = renderTemplate(string(templateContent), execValues)
if err != nil {
return errors.Wrap(err, "failed to render template")
}
}
docs, err := extractDocStrings(rendered)
if err != nil {
return errors.Wrap(err, "failed to extract documentation")
}
if strings.TrimSpace(docs) != "" {
if combinedDocs.Len() > 0 {
combinedDocs.WriteString("\n\n")
}
combinedDocs.WriteString(docs)
}
}
if outputFile != "" {
if err := os.WriteFile(outputFile, []byte(combinedDocs.String()), 0644); err != nil {
return errors.Wrapf(err, "failed to write output file %s", outputFile)
}
fmt.Printf("Documentation extracted successfully to %s\n", outputFile)
} else {
fmt.Print(combinedDocs.String())
}
return nil
}
func shouldUseHelmEngine(content string) bool {
return strings.Contains(content, ".Values")
}
func legacyContext(values map[string]interface{}) map[string]interface{} {
ctx := make(map[string]interface{}, len(values)+1)
for k, v := range values {
ctx[k] = v
}
ctx["Values"] = values
return ctx
}
func normalizeStringMaps(v interface{}) map[string]interface{} {
// Avoid unsafe type assertion; normalizeMap may return non-map types.
if v == nil {
return map[string]interface{}{}
}
normalized := normalizeMap(v)
if m, ok := normalized.(map[string]interface{}); ok {
return m
}
return map[string]interface{}{}
}
func normalizeMap(v interface{}) interface{} {
switch t := v.(type) {
case map[string]interface{}:
m := make(map[string]interface{}, len(t))
for k, val := range t {
m[k] = normalizeMap(val)
}
return m
case map[interface{}]interface{}:
m := make(map[string]interface{}, len(t))
for k, val := range t {
key := fmt.Sprintf("%v", k)
m[key] = normalizeMap(val)
}
return m
case []interface{}:
a := make([]interface{}, len(t))
for i, val := range t {
a[i] = normalizeMap(val)
}
return a
default:
return v
}
}
func extractDocStrings(yamlContent string) (string, error) {
var preflightDoc PreflightDoc
if err := yaml.Unmarshal([]byte(yamlContent), &preflightDoc); err != nil {
return "", errors.Wrap(err, "failed to parse YAML")
}
var docs strings.Builder
first := true
// Prefer beta3 analyzers docStrings
if len(preflightDoc.Spec.Analyzers) > 0 {
for _, analyzer := range preflightDoc.Spec.Analyzers {
if raw, ok := analyzer["docString"]; ok {
text, _ := raw.(string)
text = strings.TrimSpace(text)
if text == "" {
continue
}
if !first {
docs.WriteString("\n\n")
}
first = false
writeMarkdownSection(&docs, text, "")
}
}
return docs.String(), nil
}
// Fallback: legacy requirements with docString
for _, req := range preflightDoc.Requirements {
if strings.TrimSpace(req.DocString) == "" {
continue
}
if !first {
docs.WriteString("\n\n")
}
first = false
writeMarkdownSection(&docs, req.DocString, req.Name)
}
return docs.String(), nil
}
// writeMarkdownSection prints a heading from Title: or name, then the rest
func writeMarkdownSection(b *strings.Builder, docString string, fallbackName string) {
lines := strings.Split(docString, "\n")
title := strings.TrimSpace(fallbackName)
contentStart := 0
for i, line := range lines {
trim := strings.TrimSpace(line)
if strings.HasPrefix(trim, "Title:") {
parts := strings.SplitN(trim, ":", 2)
if len(parts) == 2 {
t := strings.TrimSpace(parts[1])
if t != "" {
title = t
}
}
contentStart = i + 1
break
}
}
if title != "" {
b.WriteString("### ")
b.WriteString(title)
b.WriteString("\n\n")
}
remaining := strings.Join(lines[contentStart:], "\n")
remaining = strings.TrimSpace(remaining)
if remaining != "" {
b.WriteString(remaining)
b.WriteString("\n")
}
}
// loadValuesFile loads values from a YAML file
func loadValuesFile(filename string) (map[string]interface{}, error) {
data, err := os.ReadFile(filename)
if err != nil {
return nil, err
}
var values map[string]interface{}
if err := yaml.Unmarshal(data, &values); err != nil {
return nil, errors.Wrap(err, "failed to parse values file as YAML")
}
return values, nil
}
// applySetValue applies a single --set value to the values map (Helm semantics)
func applySetValue(values map[string]interface{}, setValue string) error {
if idx := strings.Index(setValue, "="); idx > 0 {
key := setValue[:idx]
val := setValue[idx+1:]
if strings.HasPrefix(key, "Values.") {
key = strings.TrimPrefix(key, "Values.")
setValue = key + "=" + val
}
}
if err := strvals.ParseInto(setValue, values); err != nil {
return fmt.Errorf("parsing --set: %w", err)
}
return nil
}
// setNestedValue sets a value in a nested map structure
func setNestedValue(m map[string]interface{}, keys []string, value interface{}) {
if len(keys) == 0 {
return
}
if len(keys) == 1 {
m[keys[0]] = value
return
}
if _, ok := m[keys[0]]; !ok {
m[keys[0]] = make(map[string]interface{})
}
if nextMap, ok := m[keys[0]].(map[string]interface{}); ok {
setNestedValue(nextMap, keys[1:], value)
} else {
m[keys[0]] = make(map[string]interface{})
setNestedValue(m[keys[0]].(map[string]interface{}), keys[1:], value)
}
}
func mergeMaps(base, overlay map[string]interface{}) map[string]interface{} {
result := make(map[string]interface{})
for k, v := range base {
result[k] = v
}
for k, v := range overlay {
if baseVal, exists := result[k]; exists {
if baseMap, ok := baseVal.(map[string]interface{}); ok {
if overlayMap, ok := v.(map[string]interface{}); ok {
result[k] = mergeMaps(baseMap, overlayMap)
continue
}
}
}
result[k] = v
}
return result
}
func renderTemplate(templateContent string, values map[string]interface{}) (string, error) {
tmpl := template.New("preflight").Funcs(sprig.FuncMap())
tmpl, err := tmpl.Parse(templateContent)
if err != nil {
return "", errors.Wrap(err, "failed to parse template")
}
var buf bytes.Buffer
if err := tmpl.Execute(&buf, values); err != nil {
return "", errors.Wrap(err, "failed to execute template")
}
result := cleanRenderedYAML(buf.String())
return result, nil
}
func cleanRenderedYAML(content string) string {
lines := strings.Split(content, "\n")
var cleaned []string
var lastWasEmpty bool
for _, line := range lines {
trimmed := strings.TrimRight(line, " \t")
if trimmed == "" {
if !lastWasEmpty {
cleaned = append(cleaned, "")
lastWasEmpty = true
}
} else {
cleaned = append(cleaned, trimmed)
lastWasEmpty = false
}
}
for len(cleaned) > 0 && cleaned[len(cleaned)-1] == "" {
cleaned = cleaned[:len(cleaned)-1]
}
return strings.Join(cleaned, "\n") + "\n"
}
+98
View File
@@ -0,0 +1,98 @@
package cli
import (
"fmt"
"os"
"github.com/pkg/errors"
"github.com/replicatedhq/troubleshoot/pkg/constants"
"github.com/replicatedhq/troubleshoot/pkg/lint"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
func LintCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "lint [spec-files...]",
Args: cobra.MinimumNArgs(1),
Short: "Lint preflight specs for syntax and structural errors",
Long: `Lint preflight specs for syntax and structural errors.
This command validates troubleshoot specs and checks for:
- YAML syntax errors (missing colons, invalid structure)
- Missing required fields (apiVersion, kind, metadata, spec)
- Invalid template syntax ({{ .Values.* }}, {{ .Release.* }}, etc.)
- Missing analyzers or collectors
- Common structural issues
- Missing docStrings (warning)
Both v1beta2 and v1beta3 apiVersions are supported. Use 'convert' if you need a full structural conversion between schema versions.
The --fix flag can automatically repair:
- Missing colons in YAML (e.g., "metadata" "metadata:")
- Missing or malformed apiVersion line. If templating ({{ }}) or docString fields are detected, apiVersion is set to v1beta3; otherwise v1beta2.
- Template expressions missing leading dot (e.g., "{{ Values.x }}" "{{ .Values.x }}")
Examples:
# Lint a single spec file
preflight lint my-preflight.yaml
# Lint multiple spec files
preflight lint spec1.yaml spec2.yaml spec3.yaml
# Lint with automatic fixes (may need to run multiple times for complex issues)
preflight lint --fix my-preflight.yaml
# Lint and output as JSON for CI/CD integration
preflight lint --format json my-preflight.yaml
Exit codes:
0 - No errors found
2 - Validation errors found`,
PreRun: func(cmd *cobra.Command, args []string) {
viper.BindPFlags(cmd.Flags())
},
RunE: func(cmd *cobra.Command, args []string) error {
v := viper.GetViper()
opts := lint.LintOptions{
FilePaths: args,
Fix: v.GetBool("fix"),
Format: v.GetString("format"),
}
return runLint(opts)
},
}
cmd.Flags().Bool("fix", false, "Automatically fix issues where possible")
cmd.Flags().String("format", "text", "Output format: text or json")
return cmd
}
func runLint(opts lint.LintOptions) error {
// Validate file paths exist
for _, filePath := range opts.FilePaths {
if _, err := os.Stat(filePath); err != nil {
return errors.Wrapf(err, "file not found: %s", filePath)
}
}
// Run linting
results, err := lint.LintFiles(opts)
if err != nil {
return errors.Wrap(err, "failed to lint files")
}
// Format and print results
output := lint.FormatResults(results, opts.Format)
fmt.Print(output)
// Return appropriate exit code
if lint.HasErrors(results) {
os.Exit(constants.EXIT_CODE_SPEC_ISSUES)
}
return nil
}
+32 -1
View File
@@ -13,6 +13,7 @@ import (
"github.com/replicatedhq/troubleshoot/pkg/logger"
"github.com/replicatedhq/troubleshoot/pkg/preflight"
"github.com/replicatedhq/troubleshoot/pkg/types"
"github.com/replicatedhq/troubleshoot/pkg/updater"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"k8s.io/klog/v2"
@@ -37,6 +38,25 @@ that a cluster meets the requirements to run an application.`,
if err := util.StartProfiling(); err != nil {
klog.Errorf("Failed to start profiling: %v", err)
}
// Auto-update preflight unless disabled by flag or env
envAuto := os.Getenv("PREFLIGHT_AUTO_UPDATE")
autoFromEnv := true
if envAuto != "" {
if strings.EqualFold(envAuto, "0") || strings.EqualFold(envAuto, "false") {
autoFromEnv = false
}
}
if v.GetBool("auto-update") && autoFromEnv {
exe, err := os.Executable()
if err == nil {
_ = updater.CheckAndUpdate(cmd.Context(), updater.Options{
BinaryName: "preflight",
CurrentPath: exe,
Printf: func(f string, a ...interface{}) { fmt.Fprintf(os.Stderr, f, a...) },
})
}
}
},
RunE: func(cmd *cobra.Command, args []string) error {
v := viper.GetViper()
@@ -50,7 +70,7 @@ that a cluster meets the requirements to run an application.`,
err = preflight.RunPreflights(v.GetBool("interactive"), v.GetString("output"), v.GetString("format"), args)
if !v.GetBool("dry-run") && (v.GetBool("debug") || v.IsSet("v")) {
fmt.Printf("\n%s", traces.GetExporterInstance().GetSummary())
fmt.Fprintf(os.Stderr, "\n%s", traces.GetExporterInstance().GetSummary())
}
return err
@@ -66,11 +86,22 @@ that a cluster meets the requirements to run an application.`,
cmd.AddCommand(util.VersionCmd())
cmd.AddCommand(OciFetchCmd())
cmd.AddCommand(TemplateCmd())
cmd.AddCommand(DocsCmd())
cmd.AddCommand(ConvertCmd())
cmd.AddCommand(LintCmd())
preflight.AddFlags(cmd.PersistentFlags())
// 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`")
cmd.Flags().Bool("auto-update", true, "enable automatic binary self-update check and install")
// Template values for v1beta3 specs
cmd.Flags().StringSlice("values", []string{}, "Path to YAML files containing template values for v1beta3 specs (can be used multiple times)")
cmd.Flags().StringSlice("set", []string{}, "Set template values on the command line for v1beta3 specs (can be used multiple times)")
k8sutil.AddFlags(cmd.Flags())
+42
View File
@@ -0,0 +1,42 @@
package cli
import (
"github.com/replicatedhq/troubleshoot/pkg/preflight"
"github.com/spf13/cobra"
)
func TemplateCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "template [template-file]",
Short: "Render a templated preflight spec with values",
Long: `Process a templated preflight YAML file, substituting variables and removing conditional sections based on provided values.
Examples:
# Render template with default values
preflight template sample-preflight-templated.yaml
# Render template with values from files
preflight template sample-preflight-templated.yaml --values values-base.yaml --values values-prod.yaml
# Render template with inline values
preflight template sample-preflight-templated.yaml --set postgres.enabled=true --set cluster.minNodes=5
# Render template and save to file
preflight template sample-preflight-templated.yaml --output rendered.yaml`,
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
templateFile := args[0]
valuesFiles, _ := cmd.Flags().GetStringSlice("values")
outputFile, _ := cmd.Flags().GetString("output")
setValues, _ := cmd.Flags().GetStringSlice("set")
return preflight.RunTemplate(templateFile, valuesFiles, setValues, outputFile)
},
}
cmd.Flags().StringSlice("values", []string{}, "Path to YAML files containing template values (can be used multiple times)")
cmd.Flags().StringSlice("set", []string{}, "Set template values on the command line (can be used multiple times)")
cmd.Flags().StringP("output", "o", "", "Output file (default: stdout)")
return cmd
}
-174
View File
@@ -1,174 +0,0 @@
package cli
import (
"encoding/json"
"io/ioutil"
"os"
"path"
"path/filepath"
"strings"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/spf13/viper"
extensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
extensionsscheme "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme"
"k8s.io/client-go/kubernetes/scheme"
)
func RootCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "schemagen",
Short: "Generate openapischemas for the kinds in this project",
SilenceUsage: true,
PreRun: func(cmd *cobra.Command, args []string) {
viper.BindPFlags(cmd.Flags())
},
RunE: func(cmd *cobra.Command, args []string) error {
v := viper.GetViper()
return generateSchemas(v)
},
}
cobra.OnInitialize(initConfig)
cmd.Flags().String("output-dir", "./schemas", "directory to save the schemas in")
viper.BindPFlags(cmd.Flags())
viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
return cmd
}
func InitAndExecute() {
if err := RootCmd().Execute(); err != nil {
os.Exit(1)
}
}
func initConfig() {
viper.SetEnvPrefix("TROUBLESHOOT")
viper.AutomaticEnv()
}
func generateSchemas(v *viper.Viper) error {
// we generate schemas from the config/crds in the root of this project
// those crds can be created from controller-gen or by running `make openapischema`
workdir, err := os.Getwd()
if err != nil {
return errors.Wrap(err, "failed to get workdir")
}
files := []struct {
inFilename string
outFilename string
}{
{
"troubleshoot.replicated.com_preflights.yaml",
"preflight-troubleshoot-v1beta1.json",
},
{
"troubleshoot.replicated.com_analyzers.yaml",
"analyzer-troubleshoot-v1beta1.json",
},
{
"troubleshoot.replicated.com_collectors.yaml",
"collector-troubleshoot-v1beta1.json",
},
{
"troubleshoot.replicated.com_redactors.yaml",
"redactor-troubleshoot-v1beta1.json",
},
{
"troubleshoot.replicated.com_supportbundles.yaml",
"supportbundle-troubleshoot-v1beta1.json",
},
{
"troubleshoot.sh_analyzers.yaml",
"analyzer-troubleshoot-v1beta2.json",
},
{
"troubleshoot.sh_collectors.yaml",
"collector-troubleshoot-v1beta2.json",
},
{
"troubleshoot.sh_preflights.yaml",
"preflight-troubleshoot-v1beta2.json",
},
{
"troubleshoot.sh_redactors.yaml",
"redactor-troubleshoot-v1beta2.json",
},
{
"troubleshoot.sh_supportbundles.yaml",
"supportbundle-troubleshoot-v1beta2.json",
},
}
for _, file := range files {
contents, err := ioutil.ReadFile(filepath.Join(workdir, "config", "crds", file.inFilename))
if err != nil {
return errors.Wrapf(err, "failed to read crd from %s", file.inFilename)
}
if err := generateSchemaFromCRD(contents, filepath.Join(workdir, v.GetString("output-dir"), file.outFilename)); err != nil {
return errors.Wrapf(err, "failed to write crd schema to %s", file.outFilename)
}
}
return nil
}
func generateSchemaFromCRD(crd []byte, outfile string) error {
extensionsscheme.AddToScheme(scheme.Scheme)
decode := scheme.Codecs.UniversalDeserializer().Decode
obj, _, err := decode(crd, nil, nil)
if err != nil {
return errors.Wrap(err, "failed to decode crd")
}
customResourceDefinition := obj.(*extensionsv1.CustomResourceDefinition)
if len(customResourceDefinition.Spec.Versions) == 0 {
return errors.New("no versions found for CRD")
}
crdSchema := customResourceDefinition.Spec.Versions[0].Schema
if crdSchema == nil {
return errors.New("CRD has a nil schema")
}
b, err := json.MarshalIndent(crdSchema.OpenAPIV3Schema, "", " ")
if err != nil {
return errors.Wrap(err, "failed to marshal json")
}
_, err = os.Stat(outfile)
if err == nil {
if err := os.Remove(outfile); err != nil {
return errors.Wrap(err, "failed to remove file")
}
}
d, _ := path.Split(outfile)
_, err = os.Stat(d)
if os.IsNotExist(err) {
if err = os.MkdirAll(d, 0755); err != nil {
return errors.Wrap(err, "failed to mkdir")
}
}
// whoa now
// working around the fact that controller-gen doesn't have tags to generate oneOf schemas, so this is hacky.
// going to work to add an issue there to support and if they accept, this terrible thing can go away
boolStringed := strings.ReplaceAll(string(b), `"type": "BoolString"`, `"oneOf": [{"type": "string"},{"type": "boolean"}]`)
err = ioutil.WriteFile(outfile, []byte(boolStringed), 0644)
if err != nil {
return errors.Wrap(err, "failed to write file")
}
return nil
}
-9
View File
@@ -1,9 +0,0 @@
package main
import (
"github.com/replicatedhq/troubleshoot/cmd/schemagen/cli"
)
func main() {
cli.InitAndExecute()
}
+372
View File
@@ -0,0 +1,372 @@
package cli
import (
"context"
"fmt"
"time"
"github.com/pkg/errors"
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
"github.com/replicatedhq/troubleshoot/pkg/collect/autodiscovery"
"github.com/replicatedhq/troubleshoot/pkg/collect/images"
"github.com/spf13/viper"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/klog/v2"
)
// AutoDiscoveryConfig contains configuration for auto-discovery
type AutoDiscoveryConfig struct {
Enabled bool
IncludeImages bool
RBACCheck bool
Profile string
ExcludeNamespaces []string
IncludeNamespaces []string
IncludeSystemNamespaces bool
Timeout time.Duration
}
// DiscoveryProfile defines different levels of auto-discovery
type DiscoveryProfile struct {
Name string
Description string
IncludeImages bool
RBACCheck bool
MaxDepth int
Timeout time.Duration
}
// GetAutoDiscoveryConfig extracts auto-discovery configuration from viper
func GetAutoDiscoveryConfig(v *viper.Viper) AutoDiscoveryConfig {
return AutoDiscoveryConfig{
Enabled: v.GetBool("auto"),
IncludeImages: v.GetBool("include-images"),
RBACCheck: v.GetBool("rbac-check"),
Profile: v.GetString("discovery-profile"),
ExcludeNamespaces: v.GetStringSlice("exclude-namespaces"),
IncludeNamespaces: v.GetStringSlice("include-namespaces"),
IncludeSystemNamespaces: v.GetBool("include-system-namespaces"),
Timeout: 30 * time.Second, // Default timeout
}
}
// GetDiscoveryProfiles returns available discovery profiles
func GetDiscoveryProfiles() map[string]DiscoveryProfile {
return map[string]DiscoveryProfile{
"minimal": {
Name: "minimal",
Description: "Minimal collection: cluster info, basic logs",
IncludeImages: false,
RBACCheck: true,
MaxDepth: 1,
Timeout: 15 * time.Second,
},
"standard": {
Name: "standard",
Description: "Standard collection: logs, configs, secrets, events",
IncludeImages: false,
RBACCheck: true,
MaxDepth: 2,
Timeout: 30 * time.Second,
},
"comprehensive": {
Name: "comprehensive",
Description: "Comprehensive collection: everything + image metadata",
IncludeImages: true,
RBACCheck: true,
MaxDepth: 3,
Timeout: 60 * time.Second,
},
"paranoid": {
Name: "paranoid",
Description: "Paranoid collection: maximum data with extended timeouts",
IncludeImages: true,
RBACCheck: true,
MaxDepth: 5,
Timeout: 120 * time.Second,
},
}
}
// ApplyAutoDiscovery applies auto-discovery to the support bundle spec
func ApplyAutoDiscovery(ctx context.Context, client kubernetes.Interface, restConfig *rest.Config,
mainBundle *troubleshootv1beta2.SupportBundle, config AutoDiscoveryConfig, namespace string) error {
if !config.Enabled {
return nil // Auto-discovery not enabled
}
klog.V(2).Infof("Applying auto-discovery with profile: %s", config.Profile)
// Get discovery profile
profiles := GetDiscoveryProfiles()
profile, exists := profiles[config.Profile]
if !exists {
klog.Warningf("Unknown discovery profile '%s', using 'standard'", config.Profile)
profile = profiles["standard"]
}
// Override profile settings with explicit flags
if config.IncludeImages {
profile.IncludeImages = true
}
if config.Timeout > 0 {
profile.Timeout = config.Timeout
}
// Create auto-discovery options
discoveryOpts := autodiscovery.DiscoveryOptions{
IncludeImages: profile.IncludeImages,
RBACCheck: config.RBACCheck,
MaxDepth: profile.MaxDepth,
Timeout: profile.Timeout,
}
// Handle namespace filtering
if namespace != "" {
discoveryOpts.Namespaces = []string{namespace}
} else {
// Use include/exclude patterns if specified
if len(config.IncludeNamespaces) > 0 || len(config.ExcludeNamespaces) > 0 {
// Create namespace scanner to resolve include/exclude patterns
nsScanner := autodiscovery.NewNamespaceScanner(client)
scanOpts := autodiscovery.ScanOptions{
IncludePatterns: config.IncludeNamespaces,
ExcludePatterns: config.ExcludeNamespaces,
IncludeSystemNamespaces: config.IncludeSystemNamespaces,
}
targetNamespaces, err := nsScanner.GetTargetNamespaces(ctx, nil, scanOpts)
if err != nil {
klog.Warningf("Failed to resolve namespace patterns, using all accessible namespaces: %v", err)
// Continue with empty namespace list (all namespaces)
} else {
discoveryOpts.Namespaces = targetNamespaces
klog.V(2).Infof("Resolved namespace patterns to %d namespaces: %v", len(targetNamespaces), targetNamespaces)
}
}
}
// Create autodiscovery instance
discoverer, err := autodiscovery.NewDiscoverer(restConfig, client)
if err != nil {
return errors.Wrap(err, "failed to create auto-discoverer")
}
// Check if we have existing YAML collectors (Path 2) or just auto-discovery (Path 1)
hasYAMLCollectors := len(mainBundle.Spec.Collectors) > 0
var autoCollectors []autodiscovery.CollectorSpec
if hasYAMLCollectors {
// Path 2: Augment existing YAML collectors with foundational collectors
klog.V(2).Info("Auto-discovery: Augmenting YAML collectors with foundational collectors (Path 2)")
// Convert existing collectors to autodiscovery format
yamlCollectors, err := convertToCollectorSpecs(mainBundle.Spec.Collectors)
if err != nil {
return errors.Wrap(err, "failed to convert YAML collectors")
}
discoveryOpts.AugmentMode = true
autoCollectors, err = discoverer.AugmentWithFoundational(ctx, yamlCollectors, discoveryOpts)
if err != nil {
return errors.Wrap(err, "failed to augment with foundational collectors")
}
} else {
// Path 1: Pure foundational discovery
klog.V(2).Info("Auto-discovery: Collecting foundational data only (Path 1)")
discoveryOpts.FoundationalOnly = true
autoCollectors, err = discoverer.DiscoverFoundational(ctx, discoveryOpts)
if err != nil {
return errors.Wrap(err, "failed to discover foundational collectors")
}
}
// Convert auto-discovered collectors back to troubleshoot specs
troubleshootCollectors, err := convertToTroubleshootCollectors(autoCollectors)
if err != nil {
return errors.Wrap(err, "failed to convert auto-discovered collectors")
}
// Update the support bundle spec
if hasYAMLCollectors {
// Replace existing collectors with augmented set
mainBundle.Spec.Collectors = troubleshootCollectors
} else {
// Set foundational collectors
mainBundle.Spec.Collectors = troubleshootCollectors
}
klog.V(2).Infof("Auto-discovery complete: %d collectors configured", len(troubleshootCollectors))
return nil
}
// convertToCollectorSpecs converts troubleshootv1beta2.Collect to autodiscovery.CollectorSpec
func convertToCollectorSpecs(collectors []*troubleshootv1beta2.Collect) ([]autodiscovery.CollectorSpec, error) {
var specs []autodiscovery.CollectorSpec
for i, collect := range collectors {
// Determine collector type and extract relevant information
spec := autodiscovery.CollectorSpec{
Priority: 100, // High priority for YAML specs
Source: autodiscovery.SourceYAML,
}
// Map troubleshoot collectors to autodiscovery types
switch {
case collect.Logs != nil:
spec.Type = autodiscovery.CollectorTypeLogs
spec.Name = fmt.Sprintf("yaml-logs-%d", i)
spec.Namespace = collect.Logs.Namespace
spec.Spec = collect.Logs
case collect.ConfigMap != nil:
spec.Type = autodiscovery.CollectorTypeConfigMaps
spec.Name = fmt.Sprintf("yaml-configmap-%d", i)
spec.Namespace = collect.ConfigMap.Namespace
spec.Spec = collect.ConfigMap
case collect.Secret != nil:
spec.Type = autodiscovery.CollectorTypeSecrets
spec.Name = fmt.Sprintf("yaml-secret-%d", i)
spec.Namespace = collect.Secret.Namespace
spec.Spec = collect.Secret
case collect.ClusterInfo != nil:
spec.Type = autodiscovery.CollectorTypeClusterInfo
spec.Name = fmt.Sprintf("yaml-clusterinfo-%d", i)
spec.Spec = collect.ClusterInfo
case collect.ClusterResources != nil:
spec.Type = autodiscovery.CollectorTypeClusterResources
spec.Name = fmt.Sprintf("yaml-clusterresources-%d", i)
spec.Spec = collect.ClusterResources
default:
// For other collector types, create a generic spec
spec.Type = "other"
spec.Name = fmt.Sprintf("yaml-other-%d", i)
spec.Spec = collect
}
specs = append(specs, spec)
}
return specs, nil
}
// convertToTroubleshootCollectors converts autodiscovery.CollectorSpec to troubleshootv1beta2.Collect
func convertToTroubleshootCollectors(collectors []autodiscovery.CollectorSpec) ([]*troubleshootv1beta2.Collect, error) {
var troubleshootCollectors []*troubleshootv1beta2.Collect
for _, spec := range collectors {
collect, err := spec.ToTroubleshootCollect()
if err != nil {
klog.Warningf("Failed to convert collector spec %s: %v", spec.Name, err)
continue
}
troubleshootCollectors = append(troubleshootCollectors, collect)
}
return troubleshootCollectors, nil
}
// ValidateAutoDiscoveryFlags validates auto-discovery flag combinations
func ValidateAutoDiscoveryFlags(v *viper.Viper) error {
// If include-images is used without auto, it's an error
if v.GetBool("include-images") && !v.GetBool("auto") {
return errors.New("--include-images flag requires --auto flag to be enabled")
}
// Validate discovery profile
profile := v.GetString("discovery-profile")
profiles := GetDiscoveryProfiles()
if _, exists := profiles[profile]; !exists {
return fmt.Errorf("unknown discovery profile: %s. Available profiles: minimal, standard, comprehensive, paranoid", profile)
}
// Validate namespace patterns
includeNS := v.GetStringSlice("include-namespaces")
excludeNS := v.GetStringSlice("exclude-namespaces")
if len(includeNS) > 0 && len(excludeNS) > 0 {
klog.Warning("Both include-namespaces and exclude-namespaces specified. Include patterns take precedence")
}
return nil
}
// ShouldUseAutoDiscovery determines if auto-discovery should be used
func ShouldUseAutoDiscovery(v *viper.Viper, args []string) bool {
// Auto-discovery is enabled by the --auto flag
autoEnabled := v.GetBool("auto")
if !autoEnabled {
return false
}
// Auto-discovery can be used with or without YAML specs
return true
}
// GetAutoDiscoveryMode returns the auto-discovery mode based on arguments
func GetAutoDiscoveryMode(args []string, autoEnabled bool) string {
if !autoEnabled {
return "disabled"
}
if len(args) == 0 {
return "foundational-only" // Path 1
}
return "yaml-augmented" // Path 2
}
// CreateImageCollectionOptions creates image collection options from CLI config
func CreateImageCollectionOptions(config AutoDiscoveryConfig) images.CollectionOptions {
options := images.GetDefaultCollectionOptions()
// Configure based on profile and flags
profiles := GetDiscoveryProfiles()
if profile, exists := profiles[config.Profile]; exists {
options.Timeout = profile.Timeout
options.IncludeConfig = profile.Name == "comprehensive" || profile.Name == "paranoid"
options.IncludeLayers = profile.Name == "paranoid"
}
// Override based on explicit flags
if config.Timeout > 0 {
options.Timeout = config.Timeout
}
// For auto-discovery, always continue on error to maximize collection
options.ContinueOnError = true
options.EnableCache = true
return options
}
// PrintAutoDiscoveryInfo prints information about auto-discovery configuration
func PrintAutoDiscoveryInfo(config AutoDiscoveryConfig, mode string) {
if !config.Enabled {
return
}
fmt.Printf("Auto-discovery enabled (mode: %s, profile: %s)\n", mode, config.Profile)
if config.IncludeImages {
fmt.Println(" - Container image metadata collection enabled")
}
if len(config.IncludeNamespaces) > 0 {
fmt.Printf(" - Including namespaces: %v\n", config.IncludeNamespaces)
}
if len(config.ExcludeNamespaces) > 0 {
fmt.Printf(" - Excluding namespaces: %v\n", config.ExcludeNamespaces)
}
if config.IncludeSystemNamespaces {
fmt.Println(" - System namespaces included")
}
fmt.Printf(" - RBAC checking: %t\n", config.RBACCheck)
}
+389
View File
@@ -0,0 +1,389 @@
package cli
import (
"testing"
"time"
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
"github.com/replicatedhq/troubleshoot/pkg/collect/autodiscovery"
"github.com/replicatedhq/troubleshoot/pkg/collect/images"
"github.com/spf13/viper"
)
func TestGetAutoDiscoveryConfig(t *testing.T) {
tests := []struct {
name string
viperSetup func(*viper.Viper)
wantEnabled bool
wantImages bool
wantRBAC bool
wantProfile string
}{
{
name: "default config",
viperSetup: func(v *viper.Viper) {
// No flags set, should use defaults
},
wantEnabled: false,
wantImages: false,
wantRBAC: true, // Default is true
wantProfile: "standard",
},
{
name: "auto enabled",
viperSetup: func(v *viper.Viper) {
v.Set("auto", true)
},
wantEnabled: true,
wantImages: false,
wantRBAC: true,
wantProfile: "standard",
},
{
name: "auto with images",
viperSetup: func(v *viper.Viper) {
v.Set("auto", true)
v.Set("include-images", true)
},
wantEnabled: true,
wantImages: true,
wantRBAC: true,
wantProfile: "standard",
},
{
name: "comprehensive profile",
viperSetup: func(v *viper.Viper) {
v.Set("auto", true)
v.Set("discovery-profile", "comprehensive")
},
wantEnabled: true,
wantImages: false,
wantRBAC: true,
wantProfile: "comprehensive",
},
{
name: "rbac disabled",
viperSetup: func(v *viper.Viper) {
v.Set("auto", true)
v.Set("rbac-check", false)
},
wantEnabled: true,
wantImages: false,
wantRBAC: false,
wantProfile: "standard",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
v := viper.New()
// Set defaults
v.SetDefault("rbac-check", true)
v.SetDefault("discovery-profile", "standard")
// Apply test-specific setup
tt.viperSetup(v)
config := GetAutoDiscoveryConfig(v)
if config.Enabled != tt.wantEnabled {
t.Errorf("GetAutoDiscoveryConfig() enabled = %v, want %v", config.Enabled, tt.wantEnabled)
}
if config.IncludeImages != tt.wantImages {
t.Errorf("GetAutoDiscoveryConfig() includeImages = %v, want %v", config.IncludeImages, tt.wantImages)
}
if config.RBACCheck != tt.wantRBAC {
t.Errorf("GetAutoDiscoveryConfig() rbacCheck = %v, want %v", config.RBACCheck, tt.wantRBAC)
}
if config.Profile != tt.wantProfile {
t.Errorf("GetAutoDiscoveryConfig() profile = %v, want %v", config.Profile, tt.wantProfile)
}
})
}
}
func TestGetDiscoveryProfiles(t *testing.T) {
profiles := GetDiscoveryProfiles()
requiredProfiles := []string{"minimal", "standard", "comprehensive", "paranoid"}
for _, profileName := range requiredProfiles {
if profile, exists := profiles[profileName]; !exists {
t.Errorf("Missing required discovery profile: %s", profileName)
} else {
if profile.Name != profileName {
t.Errorf("Profile %s has wrong name: %s", profileName, profile.Name)
}
if profile.Description == "" {
t.Errorf("Profile %s missing description", profileName)
}
if profile.Timeout <= 0 {
t.Errorf("Profile %s has invalid timeout: %v", profileName, profile.Timeout)
}
}
}
// Check profile progression (more features as we go up)
if profiles["comprehensive"].IncludeImages && !profiles["paranoid"].IncludeImages {
t.Error("Paranoid profile should include at least everything comprehensive does")
}
}
func TestValidateAutoDiscoveryFlags(t *testing.T) {
tests := []struct {
name string
viperSetup func(*viper.Viper)
wantErr bool
}{
{
name: "valid auto discovery",
viperSetup: func(v *viper.Viper) {
v.Set("auto", true)
v.Set("include-images", true)
v.Set("discovery-profile", "standard")
},
wantErr: false,
},
{
name: "include-images without auto",
viperSetup: func(v *viper.Viper) {
v.Set("auto", false)
v.Set("include-images", true)
},
wantErr: true,
},
{
name: "invalid discovery profile",
viperSetup: func(v *viper.Viper) {
v.Set("auto", true)
v.Set("discovery-profile", "invalid-profile")
},
wantErr: true,
},
{
name: "no auto discovery",
viperSetup: func(v *viper.Viper) {
v.Set("auto", false)
},
wantErr: false,
},
{
name: "both include and exclude namespaces",
viperSetup: func(v *viper.Viper) {
v.Set("auto", true)
v.Set("include-namespaces", []string{"app1"})
v.Set("exclude-namespaces", []string{"system"})
},
wantErr: false, // Should warn but not error
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
v := viper.New()
// Set defaults
v.SetDefault("rbac-check", true)
v.SetDefault("discovery-profile", "standard")
// Apply test setup
tt.viperSetup(v)
err := ValidateAutoDiscoveryFlags(v)
if (err != nil) != tt.wantErr {
t.Errorf("ValidateAutoDiscoveryFlags() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
func TestShouldUseAutoDiscovery(t *testing.T) {
tests := []struct {
name string
viperSetup func(*viper.Viper)
args []string
want bool
}{
{
name: "auto flag enabled",
viperSetup: func(v *viper.Viper) {
v.Set("auto", true)
},
args: []string{},
want: true,
},
{
name: "auto flag disabled",
viperSetup: func(v *viper.Viper) {
v.Set("auto", false)
},
args: []string{},
want: false,
},
{
name: "auto with yaml args",
viperSetup: func(v *viper.Viper) {
v.Set("auto", true)
},
args: []string{"spec.yaml"},
want: true,
},
{
name: "no auto flag",
viperSetup: func(v *viper.Viper) {
// No auto flag set
},
args: []string{"spec.yaml"},
want: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
v := viper.New()
tt.viperSetup(v)
got := ShouldUseAutoDiscovery(v, tt.args)
if got != tt.want {
t.Errorf("ShouldUseAutoDiscovery() = %v, want %v", got, tt.want)
}
})
}
}
func TestGetAutoDiscoveryMode(t *testing.T) {
tests := []struct {
name string
args []string
autoEnabled bool
want string
}{
{
name: "foundational only",
args: []string{},
autoEnabled: true,
want: "foundational-only",
},
{
name: "yaml augmented",
args: []string{"spec.yaml"},
autoEnabled: true,
want: "yaml-augmented",
},
{
name: "disabled",
args: []string{},
autoEnabled: false,
want: "disabled",
},
{
name: "disabled with args",
args: []string{"spec.yaml"},
autoEnabled: false,
want: "disabled",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := GetAutoDiscoveryMode(tt.args, tt.autoEnabled)
if got != tt.want {
t.Errorf("GetAutoDiscoveryMode() = %v, want %v", got, tt.want)
}
})
}
}
func TestCreateImageCollectionOptions(t *testing.T) {
tests := []struct {
name string
config AutoDiscoveryConfig
checkFunc func(t *testing.T, opts images.CollectionOptions)
}{
{
name: "standard profile",
config: AutoDiscoveryConfig{
Profile: "standard",
},
checkFunc: func(t *testing.T, opts images.CollectionOptions) {
if opts.Timeout != 30*time.Second {
t.Errorf("Expected standard profile timeout 30s, got %v", opts.Timeout)
}
if !opts.ContinueOnError {
t.Error("Should continue on error for auto-discovery")
}
},
},
{
name: "comprehensive profile",
config: AutoDiscoveryConfig{
Profile: "comprehensive",
},
checkFunc: func(t *testing.T, opts images.CollectionOptions) {
if opts.Timeout != 60*time.Second {
t.Errorf("Expected comprehensive profile timeout 60s, got %v", opts.Timeout)
}
if !opts.IncludeConfig {
t.Error("Comprehensive profile should include config")
}
},
},
{
name: "paranoid profile",
config: AutoDiscoveryConfig{
Profile: "paranoid",
},
checkFunc: func(t *testing.T, opts images.CollectionOptions) {
if opts.Timeout != 120*time.Second {
t.Errorf("Expected paranoid profile timeout 120s, got %v", opts.Timeout)
}
if !opts.IncludeLayers {
t.Error("Paranoid profile should include layers")
}
},
},
{
name: "custom timeout",
config: AutoDiscoveryConfig{
Profile: "standard",
Timeout: 45 * time.Second,
},
checkFunc: func(t *testing.T, opts images.CollectionOptions) {
if opts.Timeout != 45*time.Second {
t.Errorf("Expected custom timeout 45s, got %v", opts.Timeout)
}
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
opts := CreateImageCollectionOptions(tt.config)
tt.checkFunc(t, opts)
})
}
}
func TestConvertToCollectorSpecs(t *testing.T) {
// This test would need actual troubleshootv1beta2.Collect instances
// For now, test with nil input
specs, err := convertToCollectorSpecs([]*troubleshootv1beta2.Collect{})
if err != nil {
t.Errorf("convertToCollectorSpecs() with empty input should not error: %v", err)
}
if len(specs) != 0 {
t.Errorf("convertToCollectorSpecs() with empty input should return empty slice, got %d items", len(specs))
}
}
func TestConvertToTroubleshootCollectors(t *testing.T) {
// This test would need actual autodiscovery.CollectorSpec instances
// For now, test with nil input
collectors, err := convertToTroubleshootCollectors([]autodiscovery.CollectorSpec{})
if err != nil {
t.Errorf("convertToTroubleshootCollectors() with empty input should not error: %v", err)
}
if len(collectors) != 0 {
t.Errorf("convertToTroubleshootCollectors() with empty input should return empty slice, got %d items", len(collectors))
}
}
+848
View File
@@ -0,0 +1,848 @@
package cli
import (
"archive/tar"
"bufio"
"compress/gzip"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"os"
"sort"
"strings"
"time"
"github.com/pkg/errors"
"github.com/pmezard/go-difflib/difflib"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"k8s.io/klog/v2"
)
const maxInlineDiffBytes = 256 * 1024
// DiffResult represents the result of comparing two support bundles
type DiffResult struct {
Summary DiffSummary `json:"summary"`
Changes []Change `json:"changes"`
Metadata DiffMetadata `json:"metadata"`
Significance string `json:"significance"`
}
// DiffSummary provides high-level statistics about the diff
type DiffSummary struct {
TotalChanges int `json:"totalChanges"`
FilesAdded int `json:"filesAdded"`
FilesRemoved int `json:"filesRemoved"`
FilesModified int `json:"filesModified"`
HighImpactChanges int `json:"highImpactChanges"`
}
// Change represents a single difference between bundles
type Change struct {
Type string `json:"type"` // added, removed, modified
Category string `json:"category"` // resource, log, config, etc.
Path string `json:"path"` // file path or resource path
Impact string `json:"impact"` // high, medium, low, none
Details map[string]interface{} `json:"details"` // change-specific details
Remediation *RemediationStep `json:"remediation,omitempty"`
}
// RemediationStep represents a suggested remediation action
type RemediationStep struct {
Title string `json:"title"`
Description string `json:"description"`
Command string `json:"command,omitempty"`
URL string `json:"url,omitempty"`
}
// DiffMetadata contains metadata about the diff operation
type DiffMetadata struct {
OldBundle BundleMetadata `json:"oldBundle"`
NewBundle BundleMetadata `json:"newBundle"`
GeneratedAt string `json:"generatedAt"`
Version string `json:"version"`
}
// BundleMetadata contains metadata about a support bundle
type BundleMetadata struct {
Path string `json:"path"`
Size int64 `json:"size"`
CreatedAt string `json:"createdAt,omitempty"`
NumFiles int `json:"numFiles"`
}
func Diff() *cobra.Command {
cmd := &cobra.Command{
Use: "diff <old-bundle.(tar.gz|tgz)> <new-bundle.(tar.gz|tgz)>",
Args: cobra.ExactArgs(2),
Short: "Compare two support bundles and identify changes",
Long: `Compare two support bundles to identify changes over time.
This command analyzes differences between two support bundle archives and generates
a human-readable report showing what has changed, including:
- Added, removed, or modified files
- Configuration changes
- Log differences
- Resource status changes
- Performance metric changes
Use -o to write the report to a file; otherwise it prints to stdout.`,
PreRun: func(cmd *cobra.Command, args []string) {
viper.BindPFlags(cmd.Flags())
},
RunE: func(cmd *cobra.Command, args []string) error {
v := viper.GetViper()
return runBundleDiff(v, args[0], args[1])
},
}
cmd.Flags().StringP("output", "o", "", "file path of where to save the diff report (default prints to stdout)")
cmd.Flags().Int("max-diff-lines", 200, "maximum total lines to include in an inline diff for a single file")
cmd.Flags().Int("max-diff-files", 50, "maximum number of files to include inline diffs for; additional modified files will omit inline diffs")
cmd.Flags().Bool("include-log-diffs", false, "include inline diffs for log files as well")
cmd.Flags().Int("diff-context", 3, "number of context lines to include around changes in unified diffs")
cmd.Flags().Bool("hide-inline-diffs", false, "hide inline unified diffs in the report")
cmd.Flags().String("format", "", "output format; set to 'json' to emit machine-readable JSON to stdout or -o")
return cmd
}
func runBundleDiff(v *viper.Viper, oldBundle, newBundle string) error {
klog.V(2).Infof("Comparing support bundles: %s -> %s", oldBundle, newBundle)
// Validate input files
if err := validateBundleFile(oldBundle); err != nil {
return errors.Wrap(err, "invalid old bundle")
}
if err := validateBundleFile(newBundle); err != nil {
return errors.Wrap(err, "invalid new bundle")
}
// Perform the diff (placeholder implementation)
diffResult, err := performBundleDiff(oldBundle, newBundle, v)
if err != nil {
return errors.Wrap(err, "failed to compare bundles")
}
// Output the results
if err := outputDiffResult(diffResult, v); err != nil {
return errors.Wrap(err, "failed to output diff results")
}
return nil
}
func validateBundleFile(bundlePath string) error {
if bundlePath == "" {
return errors.New("bundle path cannot be empty")
}
// Check if file exists
if _, err := os.Stat(bundlePath); os.IsNotExist(err) {
return fmt.Errorf("bundle file not found: %s", bundlePath)
}
// Support .tar.gz and .tgz bundles
lower := strings.ToLower(bundlePath)
if !(strings.HasSuffix(lower, ".tar.gz") || strings.HasSuffix(lower, ".tgz")) {
return fmt.Errorf("unsupported bundle format. Expected path to end with .tar.gz or .tgz")
}
return nil
}
func performBundleDiff(oldBundle, newBundle string, v *viper.Viper) (*DiffResult, error) {
klog.V(2).Info("Performing bundle diff analysis (streaming)...")
// Stream inventories
oldInv, err := buildInventoryFromTarGz(oldBundle)
if err != nil {
return nil, errors.Wrap(err, "failed to inventory old bundle")
}
newInv, err := buildInventoryFromTarGz(newBundle)
if err != nil {
return nil, errors.Wrap(err, "failed to inventory new bundle")
}
var changes []Change
inlineDiffsIncluded := 0
maxDiffLines := v.GetInt("max-diff-lines")
if maxDiffLines <= 0 {
maxDiffLines = 200
}
maxDiffFiles := v.GetInt("max-diff-files")
if maxDiffFiles <= 0 {
maxDiffFiles = 50
}
includeLogDiffs := v.GetBool("include-log-diffs")
diffContext := v.GetInt("diff-context")
if diffContext <= 0 {
diffContext = 3
}
// Added files
for p, nf := range newInv {
if _, ok := oldInv[p]; !ok {
ch := Change{
Type: "added",
Category: categorizePath(p),
Path: "/" + p,
Impact: estimateImpact("added", p),
Details: map[string]interface{}{
"size": nf.Size,
},
}
if rem := suggestRemediation(ch.Type, p); rem != nil {
ch.Remediation = rem
}
changes = append(changes, ch)
}
}
// Removed files
for p, of := range oldInv {
if _, ok := newInv[p]; !ok {
ch := Change{
Type: "removed",
Category: categorizePath(p),
Path: "/" + p,
Impact: estimateImpact("removed", p),
Details: map[string]interface{}{
"size": of.Size,
},
}
if rem := suggestRemediation(ch.Type, p); rem != nil {
ch.Remediation = rem
}
changes = append(changes, ch)
}
}
// Modified files
for p, of := range oldInv {
if nf, ok := newInv[p]; ok {
if of.Digest != nf.Digest {
ch := Change{
Type: "modified",
Category: categorizePath(p),
Path: "/" + p,
Impact: estimateImpact("modified", p),
Details: map[string]interface{}{},
}
if rem := suggestRemediation(ch.Type, p); rem != nil {
ch.Remediation = rem
}
changes = append(changes, ch)
}
}
}
// Sort changes deterministically: type, then path
sort.Slice(changes, func(i, j int) bool {
if changes[i].Type == changes[j].Type {
return changes[i].Path < changes[j].Path
}
return changes[i].Type < changes[j].Type
})
// Populate inline diffs lazily for the first N eligible modified files using streaming approach
for i := range changes {
if inlineDiffsIncluded >= maxDiffFiles {
break
}
ch := &changes[i]
if ch.Type != "modified" {
continue
}
allowLogs := includeLogDiffs || ch.Category != "logs"
if !allowLogs {
continue
}
// Use streaming diff generation to avoid loading large files into memory
if d := generateStreamingUnifiedDiff(oldBundle, newBundle, ch.Path, diffContext, maxDiffLines); d != "" {
if ch.Details == nil {
ch.Details = map[string]interface{}{}
}
ch.Details["diff"] = d
inlineDiffsIncluded++
}
}
// Summaries
summary := DiffSummary{}
for _, c := range changes {
switch c.Type {
case "added":
summary.FilesAdded++
case "removed":
summary.FilesRemoved++
case "modified":
summary.FilesModified++
}
if c.Impact == "high" {
summary.HighImpactChanges++
}
}
summary.TotalChanges = summary.FilesAdded + summary.FilesRemoved + summary.FilesModified
oldMeta := getBundleMetadataWithCount(oldBundle, len(oldInv))
newMeta := getBundleMetadataWithCount(newBundle, len(newInv))
result := &DiffResult{
Summary: summary,
Changes: changes,
Metadata: DiffMetadata{OldBundle: oldMeta, NewBundle: newMeta, GeneratedAt: time.Now().Format(time.RFC3339), Version: "v1"},
Significance: computeOverallSignificance(changes),
}
return result, nil
}
type inventoryFile struct {
Size int64
Digest string
}
func buildInventoryFromTarGz(bundlePath string) (map[string]inventoryFile, error) {
f, err := os.Open(bundlePath)
if err != nil {
return nil, errors.Wrap(err, "failed to open bundle")
}
defer f.Close()
gz, err := gzip.NewReader(f)
if err != nil {
return nil, errors.Wrap(err, "failed to create gzip reader")
}
defer gz.Close()
tr := tar.NewReader(gz)
inv := make(map[string]inventoryFile)
for {
hdr, err := tr.Next()
if err == io.EOF {
break
}
if err != nil {
return nil, errors.Wrap(err, "failed to read tar entry")
}
if !hdr.FileInfo().Mode().IsRegular() {
continue
}
norm := normalizePath(hdr.Name)
if norm == "" {
continue
}
h := sha256.New()
var copied int64
buf := make([]byte, 32*1024)
for copied < hdr.Size {
toRead := int64(len(buf))
if remain := hdr.Size - copied; remain < toRead {
toRead = remain
}
n, rerr := io.ReadFull(tr, buf[:toRead])
if n > 0 {
_, _ = h.Write(buf[:n])
copied += int64(n)
}
if rerr == io.EOF || rerr == io.ErrUnexpectedEOF {
break
}
if rerr != nil {
return nil, errors.Wrap(rerr, "failed to read file content")
}
}
digest := hex.EncodeToString(h.Sum(nil))
inv[norm] = inventoryFile{Size: hdr.Size, Digest: digest}
}
return inv, nil
}
func normalizePath(name string) string {
name = strings.TrimPrefix(name, "./")
if name == "" {
return name
}
i := strings.IndexByte(name, '/')
if i < 0 {
return name
}
first := name[:i]
rest := name[i+1:]
// Known domain roots we do not strip
domainRoots := map[string]bool{
"cluster-resources": true,
"all-logs": true,
"cluster-info": true,
"execution-data": true,
}
if domainRoots[first] {
return name
}
// Strip only known container prefixes
if first == "root" || strings.HasPrefix(strings.ToLower(first), "support-bundle") {
return rest
}
return name
}
func isProbablyText(sample []byte) bool {
if len(sample) == 0 {
return false
}
for _, b := range sample {
if b == 0x00 {
return false
}
if b < 0x09 {
return false
}
}
return true
}
func normalizeNewlines(s string) string {
return strings.ReplaceAll(s, "\r\n", "\n")
}
// generateStreamingUnifiedDiff creates a unified diff by streaming files line-by-line to avoid loading large files into memory
func generateStreamingUnifiedDiff(oldBundle, newBundle, path string, context, maxTotalLines int) string {
oldReader, err := createTarFileReader(oldBundle, strings.TrimPrefix(path, "/"))
if err != nil {
return ""
}
defer oldReader.Close()
newReader, err := createTarFileReader(newBundle, strings.TrimPrefix(path, "/"))
if err != nil {
return ""
}
defer newReader.Close()
// Read files line by line
oldLines, err := readLinesFromReader(oldReader, maxInlineDiffBytes)
if err != nil {
return ""
}
newLines, err := readLinesFromReader(newReader, maxInlineDiffBytes)
if err != nil {
return ""
}
// Generate diff using the existing difflib
ud := difflib.UnifiedDiff{
A: oldLines,
B: newLines,
FromFile: "old:" + path,
ToFile: "new:" + path,
Context: context,
}
s, err := difflib.GetUnifiedDiffString(ud)
if err != nil || s == "" {
return ""
}
lines := strings.Split(s, "\n")
if maxTotalLines > 0 && len(lines) > maxTotalLines {
lines = append(lines[:maxTotalLines], "... (diff truncated)")
}
if len(lines) > 0 && lines[len(lines)-1] == "" {
lines = lines[:len(lines)-1]
}
return strings.Join(lines, "\n")
}
// readLinesFromReader reads lines from a reader up to maxBytes total, returning normalized lines
func readLinesFromReader(reader io.Reader, maxBytes int) ([]string, error) {
var lines []string
var totalBytes int
scanner := bufio.NewScanner(reader)
for scanner.Scan() {
line := normalizeNewlines(scanner.Text())
lineWithNL := line + "\n"
lineBytes := len(lineWithNL)
if totalBytes+lineBytes > maxBytes {
lines = append(lines, "... (content truncated due to size)\n")
break
}
lines = append(lines, lineWithNL)
totalBytes += lineBytes
}
if err := scanner.Err(); err != nil {
return nil, err
}
return lines, nil
}
// generateUnifiedDiff builds a unified diff with headers and context, then truncates to maxTotalLines
func generateUnifiedDiff(a, b string, path string, context, maxTotalLines int) string {
ud := difflib.UnifiedDiff{
A: difflib.SplitLines(a),
B: difflib.SplitLines(b),
FromFile: "old:" + path,
ToFile: "new:" + path,
Context: context,
}
s, err := difflib.GetUnifiedDiffString(ud)
if err != nil || s == "" {
return ""
}
lines := strings.Split(s, "\n")
if maxTotalLines > 0 && len(lines) > maxTotalLines {
lines = append(lines[:maxTotalLines], "... (diff truncated)")
}
if len(lines) > 0 && lines[len(lines)-1] == "" {
lines = lines[:len(lines)-1]
}
return strings.Join(lines, "\n")
}
func categorizePath(p string) string {
if strings.HasPrefix(p, "cluster-resources/pods/logs/") || strings.Contains(p, "/logs/") || strings.HasPrefix(p, "all-logs/") || strings.HasPrefix(p, "logs/") {
return "logs"
}
if strings.HasPrefix(p, "cluster-resources/") {
rest := strings.TrimPrefix(p, "cluster-resources/")
seg := rest
if i := strings.IndexByte(rest, '/'); i >= 0 {
seg = rest[:i]
}
if seg == "" {
return "resources"
}
return "resources:" + seg
}
if strings.HasPrefix(p, "config/") || strings.HasSuffix(p, ".yaml") || strings.HasSuffix(p, ".yml") || strings.HasSuffix(p, ".json") {
return "config"
}
return "files"
}
// estimateImpact determines impact based on change type and path patterns
func estimateImpact(changeType, p string) string {
// High impact cases
if strings.HasPrefix(p, "cluster-resources/custom-resource-definitions") {
if changeType == "removed" || changeType == "modified" {
return "high"
}
}
if strings.HasPrefix(p, "cluster-resources/clusterrole") || strings.HasPrefix(p, "cluster-resources/clusterrolebindings") || strings.Contains(p, "/rolebindings/") {
if changeType != "added" { // reductions or changes can break access
return "high"
}
}
if strings.Contains(p, "/secrets/") || strings.HasSuffix(p, "-secrets.json") {
if changeType != "added" {
return "high"
}
}
if strings.HasPrefix(p, "cluster-resources/nodes") {
if changeType != "added" { // node status changes can be severe
return "high"
}
}
if strings.Contains(p, "/network-policy/") || strings.HasSuffix(p, "/networkpolicies.json") {
if changeType != "added" {
return "high"
}
}
if strings.HasPrefix(p, "cluster-resources/") && strings.Contains(p, "/kube-system") {
if changeType != "added" {
return "high"
}
}
// Medium default for cluster resources
if strings.HasPrefix(p, "cluster-resources/") {
return "medium"
}
// Logs and others default low
if strings.Contains(p, "/logs/") || strings.HasPrefix(p, "all-logs/") {
return "low"
}
return "low"
}
// suggestRemediation returns a basic remediation suggestion based on category and change
func suggestRemediation(changeType, p string) *RemediationStep {
// RBAC
if strings.HasPrefix(p, "cluster-resources/clusterrole") || strings.HasPrefix(p, "cluster-resources/clusterrolebindings") || strings.Contains(p, "/rolebindings/") {
return &RemediationStep{Description: "Validate RBAC permissions and recent changes", Command: "kubectl auth can-i --list"}
}
// CRDs
if strings.HasPrefix(p, "cluster-resources/custom-resource-definitions") {
return &RemediationStep{Description: "Check CRD presence and reconcile operator status", Command: "kubectl get crds"}
}
// Nodes
if strings.HasPrefix(p, "cluster-resources/nodes") {
return &RemediationStep{Description: "Inspect node conditions and recent events", Command: "kubectl describe nodes"}
}
// Network policy
if strings.Contains(p, "/network-policy/") || strings.HasSuffix(p, "/networkpolicies.json") {
return &RemediationStep{Description: "Validate connectivity and recent NetworkPolicy changes", Command: "kubectl get networkpolicy -A"}
}
// Secrets/Config
if strings.Contains(p, "/secrets/") || strings.HasPrefix(p, "config/") {
return &RemediationStep{Description: "Review configuration or secret changes for correctness"}
}
// Workloads
if strings.Contains(p, "/deployments/") || strings.Contains(p, "/statefulsets/") || strings.Contains(p, "/daemonsets/") {
return &RemediationStep{Description: "Check rollout and pod status", Command: "kubectl rollout status -n <ns> <kind>/<name>"}
}
return nil
}
func computeOverallSignificance(changes []Change) string {
high, medium := 0, 0
for _, c := range changes {
switch c.Impact {
case "high":
high++
case "medium":
medium++
}
}
if high > 0 {
return "high"
}
if medium > 0 {
return "medium"
}
if len(changes) > 0 {
return "low"
}
return "none"
}
func getBundleMetadata(bundlePath string) BundleMetadata {
metadata := BundleMetadata{
Path: bundlePath,
}
if stat, err := os.Stat(bundlePath); err == nil {
metadata.Size = stat.Size()
metadata.CreatedAt = stat.ModTime().Format(time.RFC3339)
}
return metadata
}
// getBundleMetadataWithCount sets NumFiles directly to avoid re-reading the archive
func getBundleMetadataWithCount(bundlePath string, numFiles int) BundleMetadata {
md := getBundleMetadata(bundlePath)
md.NumFiles = numFiles
return md
}
func outputDiffResult(result *DiffResult, v *viper.Viper) error {
outputPath := v.GetString("output")
showInlineDiffs := !v.GetBool("hide-inline-diffs")
formatMode := strings.ToLower(v.GetString("format"))
var output []byte
if formatMode == "json" {
data, err := json.MarshalIndent(result, "", " ")
if err != nil {
return errors.Wrap(err, "failed to marshal diff result to JSON")
}
output = data
} else {
output = []byte(generateTextDiffReport(result, showInlineDiffs))
}
if outputPath != "" {
// Write to file
if err := os.WriteFile(outputPath, output, 0644); err != nil {
return errors.Wrap(err, "failed to write diff output to file")
}
fmt.Printf("Diff report written to: %s\n", outputPath)
} else {
// Write to stdout
fmt.Print(string(output))
}
return nil
}
func generateTextDiffReport(result *DiffResult, showInlineDiffs bool) string {
var report strings.Builder
report.WriteString("Support Bundle Diff Report\n")
report.WriteString("==========================\n\n")
report.WriteString(fmt.Sprintf("Generated: %s\n", result.Metadata.GeneratedAt))
report.WriteString(fmt.Sprintf("Old Bundle: %s (%s)\n", result.Metadata.OldBundle.Path, formatSize(result.Metadata.OldBundle.Size)))
report.WriteString(fmt.Sprintf("New Bundle: %s (%s)\n\n", result.Metadata.NewBundle.Path, formatSize(result.Metadata.NewBundle.Size)))
// Summary
report.WriteString("Summary:\n")
report.WriteString(fmt.Sprintf(" Total Changes: %d\n", result.Summary.TotalChanges))
report.WriteString(fmt.Sprintf(" Files Added: %d\n", result.Summary.FilesAdded))
report.WriteString(fmt.Sprintf(" Files Removed: %d\n", result.Summary.FilesRemoved))
report.WriteString(fmt.Sprintf(" Files Modified: %d\n", result.Summary.FilesModified))
report.WriteString(fmt.Sprintf(" High Impact Changes: %d\n", result.Summary.HighImpactChanges))
report.WriteString(fmt.Sprintf(" Significance: %s\n\n", result.Significance))
if len(result.Changes) == 0 {
report.WriteString("No changes detected between bundles.\n")
} else {
report.WriteString("Changes:\n")
for i, change := range result.Changes {
report.WriteString(fmt.Sprintf(" %d. [%s] %s (%s impact)\n",
i+1, strings.ToUpper(change.Type), change.Path, change.Impact))
if change.Remediation != nil {
report.WriteString(fmt.Sprintf(" Remediation: %s\n", change.Remediation.Description))
}
if showInlineDiffs {
if diffStr, ok := change.Details["diff"].(string); ok && diffStr != "" {
report.WriteString(" Diff:\n")
for _, line := range strings.Split(diffStr, "\n") {
report.WriteString(" " + line + "\n")
}
}
}
}
}
return report.String()
}
func formatSize(bytes int64) string {
const unit = 1024
if bytes < unit {
return fmt.Sprintf("%d B", bytes)
}
div, exp := int64(unit), 0
for n := bytes / unit; n >= unit; n /= unit {
div *= unit
exp++
}
return fmt.Sprintf("%.1f %ciB", float64(bytes)/float64(div), "KMGTPE"[exp])
}
// tarFileReader provides a streaming interface to read a specific file from a tar.gz archive
type tarFileReader struct {
file *os.File
gz *gzip.Reader
tr *tar.Reader
found bool
header *tar.Header
}
// createTarFileReader creates a streaming reader for a specific file in a tar.gz archive
func createTarFileReader(bundlePath, normalizedPath string) (*tarFileReader, error) {
f, err := os.Open(bundlePath)
if err != nil {
return nil, err
}
gz, err := gzip.NewReader(f)
if err != nil {
f.Close()
return nil, err
}
tr := tar.NewReader(gz)
// Find the target file
for {
hdr, err := tr.Next()
if err == io.EOF {
break
}
if err != nil {
gz.Close()
f.Close()
return nil, err
}
if !hdr.FileInfo().Mode().IsRegular() {
continue
}
if normalizePath(hdr.Name) == normalizedPath {
// Check if file is probably text
sample := make([]byte, 512)
n, _ := io.ReadFull(tr, sample[:])
if n > 0 && !isProbablyText(sample[:n]) {
gz.Close()
f.Close()
return nil, fmt.Errorf("file is not text")
}
// Reopen to start from beginning of file
gz.Close()
f.Close()
f, err = os.Open(bundlePath)
if err != nil {
return nil, err
}
gz, err = gzip.NewReader(f)
if err != nil {
f.Close()
return nil, err
}
tr = tar.NewReader(gz)
// Find the file again
for {
hdr, err = tr.Next()
if err == io.EOF {
gz.Close()
f.Close()
return nil, fmt.Errorf("file not found on second pass")
}
if err != nil {
gz.Close()
f.Close()
return nil, err
}
if normalizePath(hdr.Name) == normalizedPath {
return &tarFileReader{
file: f,
gz: gz,
tr: tr,
found: true,
header: hdr,
}, nil
}
}
}
}
gz.Close()
f.Close()
return nil, fmt.Errorf("file not found: %s", normalizedPath)
}
// Read implements io.Reader interface
func (r *tarFileReader) Read(p []byte) (n int, err error) {
if !r.found {
return 0, io.EOF
}
return r.tr.Read(p)
}
// Close closes the underlying file handles
func (r *tarFileReader) Close() error {
if r.gz != nil {
r.gz.Close()
}
if r.file != nil {
return r.file.Close()
}
return nil
}
+552
View File
@@ -0,0 +1,552 @@
package cli
import (
"archive/tar"
"bytes"
"compress/gzip"
"io"
"os"
"path/filepath"
"strings"
"testing"
"time"
"github.com/spf13/viper"
)
func TestValidateBundleFile(t *testing.T) {
// Create temporary test files
tempDir := t.TempDir()
// Create bundle files
validBundle := filepath.Join(tempDir, "test-bundle.tar.gz")
if err := os.WriteFile(validBundle, []byte("dummy content"), 0644); err != nil {
t.Fatalf("Failed to create test bundle: %v", err)
}
validTgz := filepath.Join(tempDir, "test-bundle.tgz")
if err := os.WriteFile(validTgz, []byte("dummy content"), 0644); err != nil {
t.Fatalf("Failed to create test tgz bundle: %v", err)
}
tests := []struct {
name string
bundlePath string
wantErr bool
}{
{
name: "valid tar.gz bundle",
bundlePath: validBundle,
wantErr: false,
},
{
name: "valid tgz bundle",
bundlePath: validTgz,
wantErr: false,
},
{
name: "empty path",
bundlePath: "",
wantErr: true,
},
{
name: "non-existent file",
bundlePath: "/path/to/nonexistent.tar.gz",
wantErr: true,
},
{
name: "invalid extension",
bundlePath: filepath.Join(tempDir, "invalid.txt"),
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// For invalid extension test, create the file
if strings.HasSuffix(tt.bundlePath, "invalid.txt") {
os.WriteFile(tt.bundlePath, []byte("content"), 0644)
}
err := validateBundleFile(tt.bundlePath)
if (err != nil) != tt.wantErr {
t.Errorf("validateBundleFile() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
func TestGetBundleMetadata(t *testing.T) {
// Create a temporary test file
tempDir := t.TempDir()
testBundle := filepath.Join(tempDir, "test-bundle.tar.gz")
testContent := []byte("test bundle content")
if err := os.WriteFile(testBundle, testContent, 0644); err != nil {
t.Fatalf("Failed to create test bundle: %v", err)
}
metadata := getBundleMetadata(testBundle)
if metadata.Path != testBundle {
t.Errorf("getBundleMetadata() path = %v, want %v", metadata.Path, testBundle)
}
if metadata.Size != int64(len(testContent)) {
t.Errorf("getBundleMetadata() size = %v, want %v", metadata.Size, len(testContent))
}
if metadata.CreatedAt == "" {
t.Error("getBundleMetadata() createdAt should not be empty")
}
// Validate timestamp format
if _, err := time.Parse(time.RFC3339, metadata.CreatedAt); err != nil {
t.Errorf("getBundleMetadata() createdAt has invalid format: %v", err)
}
}
func TestPerformBundleDiff(t *testing.T) {
// Create temporary test bundles
tempDir := t.TempDir()
oldBundle := filepath.Join(tempDir, "old-bundle.tar.gz")
newBundle := filepath.Join(tempDir, "new-bundle.tar.gz")
if err := writeTarGz(oldBundle, map[string]string{
"root/cluster-resources/version.txt": "v1\n",
"root/logs/app.log": "line1\n",
}); err != nil {
t.Fatalf("Failed to create old bundle: %v", err)
}
if err := writeTarGz(newBundle, map[string]string{
"root/cluster-resources/version.txt": "v2\n",
"root/logs/app.log": "line1\nline2\n",
"root/added.txt": "new\n",
}); err != nil {
t.Fatalf("Failed to create new bundle: %v", err)
}
v := viper.New()
result, err := performBundleDiff(oldBundle, newBundle, v)
if err != nil {
t.Fatalf("performBundleDiff() error = %v", err)
}
if result == nil {
t.Fatal("performBundleDiff() returned nil result")
}
// Verify result structure
if result.Metadata.Version != "v1" {
t.Errorf("performBundleDiff() version = %v, want v1", result.Metadata.Version)
}
if result.Metadata.OldBundle.Path != oldBundle {
t.Errorf("performBundleDiff() old bundle path = %v, want %v", result.Metadata.OldBundle.Path, oldBundle)
}
if result.Metadata.NewBundle.Path != newBundle {
t.Errorf("performBundleDiff() new bundle path = %v, want %v", result.Metadata.NewBundle.Path, newBundle)
}
if result.Metadata.GeneratedAt == "" {
t.Error("performBundleDiff() generatedAt should not be empty")
}
}
// writeTarGz creates a gzipped tar file at tarPath with the provided files map.
// Keys are entry names inside the archive, values are file contents.
func writeTarGz(tarPath string, files map[string]string) error {
f, err := os.Create(tarPath)
if err != nil {
return err
}
defer f.Close()
gz := gzip.NewWriter(f)
defer gz.Close()
tw := tar.NewWriter(gz)
defer tw.Close()
for name, content := range files {
data := []byte(content)
hdr := &tar.Header{
Name: name,
Mode: 0644,
Size: int64(len(data)),
Typeflag: tar.TypeReg,
}
if err := tw.WriteHeader(hdr); err != nil {
return err
}
if _, err := bytes.NewReader(data).WriteTo(tw); err != nil {
return err
}
}
return nil
}
func TestGenerateTextDiffReport(t *testing.T) {
result := &DiffResult{
Summary: DiffSummary{
TotalChanges: 3,
FilesAdded: 1,
FilesRemoved: 1,
FilesModified: 1,
HighImpactChanges: 1,
},
Changes: []Change{
{
Type: "added",
Category: "config",
Path: "/new-config.yaml",
Impact: "medium",
Remediation: &RemediationStep{
Description: "Review new configuration",
},
},
{
Type: "removed",
Category: "resource",
Path: "/old-deployment.yaml",
Impact: "high",
},
},
Metadata: DiffMetadata{
OldBundle: BundleMetadata{
Path: "/old/bundle.tar.gz",
Size: 1024,
},
NewBundle: BundleMetadata{
Path: "/new/bundle.tar.gz",
Size: 2048,
},
GeneratedAt: "2023-01-01T00:00:00Z",
},
Significance: "high",
}
report := generateTextDiffReport(result, true)
// Check that report contains expected elements
expectedStrings := []string{
"Support Bundle Diff Report",
"Total Changes: 3",
"Files Added: 1",
"High Impact Changes: 1",
"Significance: high",
"/new-config.yaml",
"/old-deployment.yaml",
"Remediation: Review new configuration",
}
for _, expected := range expectedStrings {
if !strings.Contains(report, expected) {
t.Errorf("generateTextDiffReport() missing expected string: %s", expected)
}
}
}
func TestOutputDiffResult_JSON(t *testing.T) {
// Minimal result
result := &DiffResult{
Summary: DiffSummary{},
Metadata: DiffMetadata{
OldBundle: BundleMetadata{Path: "/old.tar.gz"},
NewBundle: BundleMetadata{Path: "/new.tar.gz"},
GeneratedAt: time.Now().Format(time.RFC3339),
Version: "v1",
},
Changes: []Change{{Type: "modified", Category: "files", Path: "/a", Impact: "low"}},
Significance: "low",
}
v := viper.New()
v.Set("format", "json")
// Write to a temp file via -o to exercise file write path
tempDir := t.TempDir()
outPath := filepath.Join(tempDir, "diff.json")
v.Set("output", outPath)
if err := outputDiffResult(result, v); err != nil {
t.Fatalf("outputDiffResult(json) error = %v", err)
}
data, err := os.ReadFile(outPath)
if err != nil {
t.Fatalf("failed to read output: %v", err)
}
// Basic JSON sanity checks
s := string(data)
if !strings.Contains(s, "\"summary\"") || !strings.Contains(s, "\"changes\"") {
t.Fatalf("json output missing keys: %s", s)
}
if !strings.Contains(s, "\"path\": \"/a\"") {
t.Fatalf("json output missing change path: %s", s)
}
}
func TestGenerateTextDiffReport_DiffVisibility(t *testing.T) {
result := &DiffResult{
Summary: DiffSummary{TotalChanges: 1, FilesModified: 1},
Changes: []Change{
{
Type: "modified",
Category: "files",
Path: "/path.txt",
Impact: "low",
Details: map[string]interface{}{"diff": "--- old:/path.txt\n+++ new:/path.txt\n@@\n-a\n+b"},
},
},
Metadata: DiffMetadata{GeneratedAt: time.Now().Format(time.RFC3339)},
}
reportShown := generateTextDiffReport(result, true)
if !strings.Contains(reportShown, "Diff:") || !strings.Contains(reportShown, "+ new:/path.txt") {
t.Fatalf("expected diff to be shown when enabled; got: %s", reportShown)
}
reportHidden := generateTextDiffReport(result, false)
if strings.Contains(reportHidden, "Diff:") {
t.Fatalf("expected diff to be hidden when disabled; got: %s", reportHidden)
}
}
func TestCategorizePath(t *testing.T) {
cases := []struct {
in string
out string
}{
{"cluster-resources/pods/logs/ns/pod/container.log", "logs"},
{"some/ns/logs/thing.log", "logs"},
{"all-logs/ns/pod/container.log", "logs"},
{"logs/app.log", "logs"},
{"cluster-resources/configmaps/ns.json", "resources:configmaps"},
{"cluster-resources/", "resources"},
{"config/settings.yaml", "config"},
{"random/file.json", "config"},
{"random/file.txt", "files"},
}
for _, c := range cases {
if got := categorizePath(c.in); got != c.out {
t.Errorf("categorizePath(%q)=%q want %q", c.in, got, c.out)
}
}
}
func TestNormalizePath(t *testing.T) {
cases := []struct {
in string
out string
}{
{"root/foo.txt", "foo.txt"},
{"support-bundle-123/foo.txt", "foo.txt"},
{"Support-Bundle-ABC/bar/baz.txt", "bar/baz.txt"},
{"cluster-resources/pods/logs/whatever.log", "cluster-resources/pods/logs/whatever.log"},
{"all-logs/whatever.log", "all-logs/whatever.log"},
}
for _, c := range cases {
if got := normalizePath(c.in); got != c.out {
t.Errorf("normalizePath(%q)=%q want %q", c.in, got, c.out)
}
}
}
func TestGenerateUnifiedDiff_TruncationAndContext(t *testing.T) {
old := "line1\nline2\nline3\nline4\nline5\n"
newv := "line1\nline2-mod\nline3\nline4\nline5\n"
// context=1 should include headers and minimal context; max lines small to force truncation
diff := generateUnifiedDiff(old, newv, "/file.txt", 1, 5)
if diff == "" {
t.Fatal("expected non-empty diff")
}
if !strings.Contains(diff, "old:/file.txt") || !strings.Contains(diff, "new:/file.txt") {
t.Errorf("diff missing headers: %s", diff)
}
if !strings.Contains(diff, "... (diff truncated)") {
t.Errorf("expected truncated marker in diff: %s", diff)
}
}
func TestFormatSize(t *testing.T) {
tests := []struct {
name string
bytes int64
want string
}{
{
name: "bytes",
bytes: 512,
want: "512 B",
},
{
name: "kilobytes",
bytes: 1536, // 1.5 KB
want: "1.5 KiB",
},
{
name: "megabytes",
bytes: 1572864, // 1.5 MB
want: "1.5 MiB",
},
{
name: "zero",
bytes: 0,
want: "0 B",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := formatSize(tt.bytes)
if got != tt.want {
t.Errorf("formatSize() = %v, want %v", got, tt.want)
}
})
}
}
func TestCreateTarFileReader(t *testing.T) {
tempDir := t.TempDir()
bundlePath := filepath.Join(tempDir, "test-bundle.tar.gz")
// Create test bundle with text and binary files
testFiles := map[string]string{
"root/text-file.txt": "line1\nline2\nline3\n",
"root/config.yaml": "key: value\nother: data\n",
"root/binary-file.bin": string([]byte{0x00, 0x01, 0x02, 0xFF}), // Binary content
}
if err := writeTarGz(bundlePath, testFiles); err != nil {
t.Fatalf("Failed to create test bundle: %v", err)
}
// Test reading existing text file
reader, err := createTarFileReader(bundlePath, "text-file.txt")
if err != nil {
t.Fatalf("createTarFileReader() error = %v", err)
}
defer reader.Close()
content := make([]byte, 100)
n, err := reader.Read(content)
if err != nil && err != io.EOF {
t.Errorf("Read() error = %v", err)
}
contentStr := string(content[:n])
if !strings.Contains(contentStr, "line1") {
t.Errorf("Expected file content not found, got: %s", contentStr)
}
// Test reading non-existent file
_, err = createTarFileReader(bundlePath, "non-existent.txt")
if err == nil {
t.Error("Expected error for non-existent file")
}
// Test reading binary file (should fail)
_, err = createTarFileReader(bundlePath, "binary-file.bin")
if err == nil {
t.Error("Expected error for binary file")
}
}
func TestGenerateStreamingUnifiedDiff(t *testing.T) {
tempDir := t.TempDir()
oldBundle := filepath.Join(tempDir, "old-bundle.tar.gz")
newBundle := filepath.Join(tempDir, "new-bundle.tar.gz")
// Create bundles with different versions of the same file
if err := writeTarGz(oldBundle, map[string]string{
"root/config.yaml": "version: 1.0\napp: test\nfeature: disabled\n",
}); err != nil {
t.Fatalf("Failed to create old bundle: %v", err)
}
if err := writeTarGz(newBundle, map[string]string{
"root/config.yaml": "version: 2.0\napp: test\nfeature: enabled\n",
}); err != nil {
t.Fatalf("Failed to create new bundle: %v", err)
}
// Generate streaming diff
diff := generateStreamingUnifiedDiff(oldBundle, newBundle, "/config.yaml", 3, 100)
// Verify diff content
if diff == "" {
t.Error("Expected non-empty diff")
}
expectedStrings := []string{
"old:/config.yaml",
"new:/config.yaml",
"-version: 1.0",
"+version: 2.0",
"-feature: disabled",
"+feature: enabled",
}
for _, expected := range expectedStrings {
if !strings.Contains(diff, expected) {
t.Errorf("Diff missing expected string '%s'. Got: %s", expected, diff)
}
}
}
func TestReadLinesFromReader(t *testing.T) {
tests := []struct {
name string
content string
maxBytes int
wantLen int
wantLast string
}{
{
name: "small content",
content: "line1\nline2\nline3\n",
maxBytes: 1000,
wantLen: 3,
wantLast: "line3\n",
},
{
name: "content exceeds limit",
content: "line1\nline2\nline3\nline4\nline5\n",
maxBytes: 15, // Only allows first 2 lines plus truncation marker
wantLen: 3,
wantLast: "... (content truncated due to size)\n",
},
{
name: "empty content",
content: "",
maxBytes: 1000,
wantLen: 0,
wantLast: "",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
reader := strings.NewReader(tt.content)
lines, err := readLinesFromReader(reader, tt.maxBytes)
if err != nil {
t.Errorf("readLinesFromReader() error = %v", err)
}
if len(lines) != tt.wantLen {
t.Errorf("readLinesFromReader() got %d lines, want %d", len(lines), tt.wantLen)
}
if tt.wantLen > 0 && lines[len(lines)-1] != tt.wantLast {
t.Errorf("readLinesFromReader() last line = %s, want %s", lines[len(lines)-1], tt.wantLast)
}
})
}
}
+239
View File
@@ -0,0 +1,239 @@
package cli
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
"github.com/pkg/errors"
"k8s.io/klog/v2"
)
// DiscoveryConfig represents the configuration for auto-discovery
type DiscoveryConfig struct {
Version string `json:"version" yaml:"version"`
Profiles map[string]DiscoveryProfile `json:"profiles" yaml:"profiles"`
Patterns DiscoveryPatterns `json:"patterns" yaml:"patterns"`
}
// DiscoveryPatterns defines inclusion/exclusion patterns for discovery
type DiscoveryPatterns struct {
NamespacePatterns PatternConfig `json:"namespacePatterns" yaml:"namespacePatterns"`
ResourceTypePatterns PatternConfig `json:"resourceTypePatterns" yaml:"resourceTypePatterns"`
RegistryPatterns PatternConfig `json:"registryPatterns" yaml:"registryPatterns"`
}
// PatternConfig defines include/exclude patterns
type PatternConfig struct {
Include []string `json:"include" yaml:"include"`
Exclude []string `json:"exclude" yaml:"exclude"`
}
// LoadDiscoveryConfig loads discovery configuration from file or returns defaults
func LoadDiscoveryConfig(configPath string) (*DiscoveryConfig, error) {
// If no config path specified, use built-in defaults
if configPath == "" {
return getDefaultDiscoveryConfig(), nil
}
// Check if config file exists
if _, err := os.Stat(configPath); os.IsNotExist(err) {
klog.V(2).Infof("Discovery config file not found: %s, using defaults", configPath)
return getDefaultDiscoveryConfig(), nil
}
// Read config file
data, err := ioutil.ReadFile(configPath)
if err != nil {
return nil, errors.Wrap(err, "failed to read discovery config file")
}
// Parse config file (support JSON for now)
var config DiscoveryConfig
if err := json.Unmarshal(data, &config); err != nil {
return nil, errors.Wrap(err, "failed to parse discovery config")
}
// Validate config
if err := validateDiscoveryConfig(&config); err != nil {
return nil, errors.Wrap(err, "invalid discovery config")
}
return &config, nil
}
// getDefaultDiscoveryConfig returns the built-in default configuration
func getDefaultDiscoveryConfig() *DiscoveryConfig {
return &DiscoveryConfig{
Version: "v1",
Profiles: GetDiscoveryProfiles(),
Patterns: DiscoveryPatterns{
NamespacePatterns: PatternConfig{
Include: []string{"*"}, // Include all by default
Exclude: []string{
"kube-system",
"kube-public",
"kube-node-lease",
"kubernetes-dashboard",
"cattle-*",
"rancher-*",
},
},
ResourceTypePatterns: PatternConfig{
Include: []string{
"pods",
"deployments",
"services",
"configmaps",
"secrets",
"events",
},
Exclude: []string{
"*.tmp",
"*.log", // Exclude raw log files in favor of structured logs
},
},
RegistryPatterns: PatternConfig{
Include: []string{"*"}, // Include all registries
Exclude: []string{}, // No exclusions by default
},
},
}
}
// validateDiscoveryConfig validates a discovery configuration
func validateDiscoveryConfig(config *DiscoveryConfig) error {
if config.Version == "" {
config.Version = "v1" // Default version
}
if config.Profiles == nil {
return errors.New("profiles section is required")
}
// Validate each profile
requiredProfiles := []string{"minimal", "standard", "comprehensive"}
for _, profileName := range requiredProfiles {
if _, exists := config.Profiles[profileName]; !exists {
return fmt.Errorf("required profile missing: %s", profileName)
}
}
return nil
}
// ApplyDiscoveryPatterns applies include/exclude patterns to a list
func ApplyDiscoveryPatterns(items []string, patterns PatternConfig) ([]string, error) {
if len(patterns.Include) == 0 && len(patterns.Exclude) == 0 {
return items, nil // No patterns to apply
}
var result []string
for _, item := range items {
include := true
// Check exclude patterns first
for _, excludePattern := range patterns.Exclude {
if matched, err := matchPattern(item, excludePattern); err != nil {
return nil, errors.Wrapf(err, "invalid exclude pattern: %s", excludePattern)
} else if matched {
include = false
break
}
}
// If not excluded, check include patterns
if include && len(patterns.Include) > 0 {
include = false // Default to exclude if include patterns exist
for _, includePattern := range patterns.Include {
if matched, err := matchPattern(item, includePattern); err != nil {
return nil, errors.Wrapf(err, "invalid include pattern: %s", includePattern)
} else if matched {
include = true
break
}
}
}
if include {
result = append(result, item)
}
}
return result, nil
}
// matchPattern checks if an item matches a glob pattern
func matchPattern(item, pattern string) (bool, error) {
// Simple glob pattern matching
if pattern == "*" {
return true, nil
}
if pattern == item {
return true, nil
}
// Handle basic wildcard patterns
if strings.HasPrefix(pattern, "*") && strings.HasSuffix(pattern, "*") {
// Pattern is "*substring*"
substring := pattern[1 : len(pattern)-1]
return strings.Contains(item, substring), nil
}
if strings.HasPrefix(pattern, "*") {
// Pattern is "*suffix"
suffix := pattern[1:]
return strings.HasSuffix(item, suffix), nil
}
if strings.HasSuffix(pattern, "*") {
// Pattern is "prefix*"
prefix := pattern[:len(pattern)-1]
return strings.HasPrefix(item, prefix), nil
}
return false, nil
}
// SaveDiscoveryConfig saves discovery configuration to a file
func SaveDiscoveryConfig(config *DiscoveryConfig, configPath string) error {
// Create directory if it doesn't exist
dir := filepath.Dir(configPath)
if err := os.MkdirAll(dir, 0755); err != nil {
return errors.Wrap(err, "failed to create config directory")
}
// Marshal to JSON
data, err := json.MarshalIndent(config, "", " ")
if err != nil {
return errors.Wrap(err, "failed to marshal config")
}
// Write to file
if err := ioutil.WriteFile(configPath, data, 0644); err != nil {
return errors.Wrap(err, "failed to write config file")
}
return nil
}
// GetDiscoveryConfigPath returns the default path for discovery configuration
func GetDiscoveryConfigPath() string {
homeDir, err := os.UserHomeDir()
if err != nil {
return "./troubleshoot-discovery.json"
}
return filepath.Join(homeDir, ".troubleshoot", "discovery.json")
}
// CreateDefaultDiscoveryConfigFile creates a default discovery config file
func CreateDefaultDiscoveryConfigFile(configPath string) error {
config := getDefaultDiscoveryConfig()
return SaveDiscoveryConfig(config, configPath)
}
@@ -0,0 +1,422 @@
package cli
import (
"fmt"
"os"
"path/filepath"
"strings"
"testing"
)
func TestLoadDiscoveryConfig(t *testing.T) {
tests := []struct {
name string
setupConfig func(string) error
configPath string
wantErr bool
checkFunc func(*testing.T, *DiscoveryConfig)
}{
{
name: "no config path - use defaults",
configPath: "",
wantErr: false,
checkFunc: func(t *testing.T, config *DiscoveryConfig) {
if config.Version != "v1" {
t.Errorf("Expected version v1, got %s", config.Version)
}
if len(config.Profiles) == 0 {
t.Error("Default config should have profiles")
}
},
},
{
name: "non-existent config file - use defaults",
configPath: "/non/existent/path.json",
wantErr: false,
checkFunc: func(t *testing.T, config *DiscoveryConfig) {
if config.Version != "v1" {
t.Errorf("Expected version v1, got %s", config.Version)
}
},
},
{
name: "valid config file",
setupConfig: func(path string) error {
configContent := `{
"version": "v1",
"profiles": {
"minimal": {
"name": "minimal",
"description": "Minimal collection",
"includeImages": false,
"rbacCheck": true,
"maxDepth": 1,
"timeout": 15000000000
},
"standard": {
"name": "standard",
"description": "Standard collection",
"includeImages": false,
"rbacCheck": true,
"maxDepth": 2,
"timeout": 30000000000
},
"comprehensive": {
"name": "comprehensive",
"description": "Comprehensive collection",
"includeImages": true,
"rbacCheck": true,
"maxDepth": 3,
"timeout": 60000000000
}
},
"patterns": {
"namespacePatterns": {
"include": ["app-*"],
"exclude": ["kube-*"]
}
}
}`
return os.WriteFile(path, []byte(configContent), 0644)
},
wantErr: false,
checkFunc: func(t *testing.T, config *DiscoveryConfig) {
if config.Version != "v1" {
t.Errorf("Expected version v1, got %s", config.Version)
}
if len(config.Profiles) == 0 {
t.Error("Config should have profiles")
}
},
},
{
name: "invalid json config",
setupConfig: func(path string) error {
return os.WriteFile(path, []byte(`{invalid json`), 0644)
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var configPath string
if tt.configPath != "" {
configPath = tt.configPath
}
// Setup config file if needed
if tt.setupConfig != nil {
tempDir := t.TempDir()
configPath = filepath.Join(tempDir, "config.json")
if err := tt.setupConfig(configPath); err != nil {
t.Fatalf("Failed to setup config: %v", err)
}
}
config, err := LoadDiscoveryConfig(configPath)
if (err != nil) != tt.wantErr {
t.Errorf("LoadDiscoveryConfig() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !tt.wantErr && tt.checkFunc != nil {
tt.checkFunc(t, config)
}
})
}
}
func TestApplyDiscoveryPatterns(t *testing.T) {
tests := []struct {
name string
items []string
patterns PatternConfig
want []string
}{
{
name: "no patterns",
items: []string{"app1", "app2", "kube-system"},
patterns: PatternConfig{
Include: []string{},
Exclude: []string{},
},
want: []string{"app1", "app2", "kube-system"},
},
{
name: "exclude patterns only",
items: []string{"app1", "app2", "kube-system", "kube-public"},
patterns: PatternConfig{
Include: []string{},
Exclude: []string{"kube-*"},
},
want: []string{"app1", "app2"},
},
{
name: "include patterns only",
items: []string{"app1", "app2", "kube-system"},
patterns: PatternConfig{
Include: []string{"app*"},
Exclude: []string{},
},
want: []string{"app1", "app2"},
},
{
name: "include and exclude patterns",
items: []string{"app1", "app2", "app-system", "kube-system"},
patterns: PatternConfig{
Include: []string{"app*"},
Exclude: []string{"*system"},
},
want: []string{"app1", "app2"}, // app-system excluded, kube-system not included
},
{
name: "exact match patterns",
items: []string{"app1", "app2", "special"},
patterns: PatternConfig{
Include: []string{"special", "app1"},
Exclude: []string{},
},
want: []string{"app1", "special"},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := ApplyDiscoveryPatterns(tt.items, tt.patterns)
if err != nil {
t.Errorf("ApplyDiscoveryPatterns() error = %v", err)
return
}
if len(got) != len(tt.want) {
t.Errorf("ApplyDiscoveryPatterns() length = %v, want %v", len(got), len(tt.want))
return
}
// Check that all expected items are present
gotMap := make(map[string]bool)
for _, item := range got {
gotMap[item] = true
}
for _, wantItem := range tt.want {
if !gotMap[wantItem] {
t.Errorf("ApplyDiscoveryPatterns() missing expected item: %s", wantItem)
}
}
})
}
}
func TestMatchPattern(t *testing.T) {
tests := []struct {
name string
item string
pattern string
want bool
wantErr bool
}{
{
name: "exact match",
item: "app1",
pattern: "app1",
want: true,
},
{
name: "wildcard all",
item: "anything",
pattern: "*",
want: true,
},
{
name: "prefix wildcard",
item: "app-namespace",
pattern: "app*",
want: true,
},
{
name: "suffix wildcard",
item: "kube-system",
pattern: "*system",
want: true,
},
{
name: "substring wildcard",
item: "my-app-namespace",
pattern: "*app*",
want: true,
},
{
name: "no match",
item: "different",
pattern: "app*",
want: false,
},
{
name: "prefix no match",
item: "other-app",
pattern: "app*",
want: false,
},
{
name: "suffix no match",
item: "system-app",
pattern: "*system",
want: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := matchPattern(tt.item, tt.pattern)
if (err != nil) != tt.wantErr {
t.Errorf("matchPattern() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("matchPattern() = %v, want %v", got, tt.want)
}
})
}
}
func TestSaveDiscoveryConfig(t *testing.T) {
config := getDefaultDiscoveryConfig()
tempDir := t.TempDir()
configPath := filepath.Join(tempDir, "test-config.json")
err := SaveDiscoveryConfig(config, configPath)
if err != nil {
t.Fatalf("SaveDiscoveryConfig() error = %v", err)
}
// Verify file was created
if _, err := os.Stat(configPath); os.IsNotExist(err) {
t.Error("SaveDiscoveryConfig() did not create config file")
}
// Verify we can load it back
loadedConfig, err := LoadDiscoveryConfig(configPath)
if err != nil {
t.Fatalf("Failed to reload saved config: %v", err)
}
if loadedConfig.Version != config.Version {
t.Errorf("Reloaded config version = %v, want %v", loadedConfig.Version, config.Version)
}
}
func TestGetDiscoveryConfigPath(t *testing.T) {
path := GetDiscoveryConfigPath()
if path == "" {
t.Error("GetDiscoveryConfigPath() should not return empty string")
}
// Should end with expected filename
expectedSuffix := "discovery.json"
if !strings.HasSuffix(path, expectedSuffix) {
t.Errorf("GetDiscoveryConfigPath() should end with %s, got %s", expectedSuffix, path)
}
}
func TestValidateDiscoveryConfig(t *testing.T) {
tests := []struct {
name string
config *DiscoveryConfig
wantErr bool
}{
{
name: "valid config",
config: &DiscoveryConfig{
Version: "v1",
Profiles: GetDiscoveryProfiles(),
},
wantErr: false,
},
{
name: "missing version gets default",
config: &DiscoveryConfig{
Profiles: GetDiscoveryProfiles(),
},
wantErr: false,
},
{
name: "nil profiles",
config: &DiscoveryConfig{
Version: "v1",
Profiles: nil,
},
wantErr: true,
},
{
name: "missing required profile",
config: &DiscoveryConfig{
Version: "v1",
Profiles: map[string]DiscoveryProfile{
"custom": {Name: "custom"},
},
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := validateDiscoveryConfig(tt.config)
if (err != nil) != tt.wantErr {
t.Errorf("validateDiscoveryConfig() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
func BenchmarkMatchPattern(b *testing.B) {
testCases := []struct {
item string
pattern string
}{
{"app-namespace", "app*"},
{"kube-system", "*system"},
{"my-app-test", "*app*"},
{"exact-match", "exact-match"},
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
for _, tc := range testCases {
_, err := matchPattern(tc.item, tc.pattern)
if err != nil {
b.Fatalf("matchPattern failed: %v", err)
}
}
}
}
func BenchmarkApplyDiscoveryPatterns(b *testing.B) {
items := make([]string, 100)
for i := 0; i < 100; i++ {
if i%3 == 0 {
items[i] = fmt.Sprintf("app-%d", i)
} else if i%3 == 1 {
items[i] = fmt.Sprintf("kube-system-%d", i)
} else {
items[i] = fmt.Sprintf("other-%d", i)
}
}
patterns := PatternConfig{
Include: []string{"app*", "other*"},
Exclude: []string{"*system*"},
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := ApplyDiscoveryPatterns(items, patterns)
if err != nil {
b.Fatalf("ApplyDiscoveryPatterns failed: %v", err)
}
}
}
+20 -96
View File
@@ -2,10 +2,6 @@ package cli
import (
"fmt"
"io/ioutil"
"os"
"path"
"time"
"github.com/mitchellh/go-wordwrap"
"github.com/pkg/errors"
@@ -19,15 +15,14 @@ import (
var (
selectedResult = 0
table = widgets.NewTable()
isShowingSaved = false
)
func showInteractiveResults(supportBundleName string, analyzeResults []*analyzerunner.AnalyzeResult) error {
func showInteractiveResults(supportBundleName string, analyzeResults []*analyzerunner.AnalyzeResult, archivePath string) error {
if err := ui.Init(); err != nil {
return errors.Wrap(err, "failed to create terminal ui")
}
defer ui.Close()
drawUI(supportBundleName, analyzeResults)
drawUI(supportBundleName, analyzeResults, archivePath)
uiEvents := ui.PollEvents()
for {
@@ -37,29 +32,10 @@ func showInteractiveResults(supportBundleName string, analyzeResults []*analyzer
case "<C-c>":
return nil
case "q":
if isShowingSaved == true {
isShowingSaved = false
ui.Clear()
drawUI(supportBundleName, analyzeResults)
} else {
return nil
}
case "s":
filename, err := save(analyzeResults)
if err != nil {
// show
} else {
showSaved(filename)
go func() {
time.Sleep(time.Second * 5)
isShowingSaved = false
ui.Clear()
drawUI(supportBundleName, analyzeResults)
}()
}
return nil
case "<Resize>":
ui.Clear()
drawUI(supportBundleName, analyzeResults)
drawUI(supportBundleName, analyzeResults, archivePath)
case "<Down>":
if selectedResult < len(analyzeResults)-1 {
selectedResult++
@@ -69,7 +45,7 @@ func showInteractiveResults(supportBundleName string, analyzeResults []*analyzer
}
table.ScrollDown()
ui.Clear()
drawUI(supportBundleName, analyzeResults)
drawUI(supportBundleName, analyzeResults, archivePath)
case "<Up>":
if selectedResult > 0 {
selectedResult--
@@ -79,16 +55,16 @@ func showInteractiveResults(supportBundleName string, analyzeResults []*analyzer
}
table.ScrollUp()
ui.Clear()
drawUI(supportBundleName, analyzeResults)
drawUI(supportBundleName, analyzeResults, archivePath)
}
}
}
}
func drawUI(supportBundleName string, analyzeResults []*analyzerunner.AnalyzeResult) {
func drawUI(supportBundleName string, analyzeResults []*analyzerunner.AnalyzeResult, archivePath string) {
drawGrid(analyzeResults)
drawHeader(supportBundleName)
drawFooter()
drawFooter(archivePath)
}
func drawGrid(analyzeResults []*analyzerunner.AnalyzeResult) {
@@ -101,9 +77,7 @@ func drawHeader(supportBundleName string) {
title := widgets.NewParagraph()
title.Text = fmt.Sprintf("%s Support Bundle Analysis", util.AppName(supportBundleName))
title.TextStyle.Fg = ui.ColorWhite
title.TextStyle.Bg = ui.ColorClear
title.TextStyle.Modifier = ui.ModifierBold
title.TextStyle = ui.NewStyle(ui.ColorWhite, ui.ColorClear, ui.ModifierBold)
title.Border = false
left := termWidth/2 - 2*len(title.Text)/3
@@ -113,11 +87,18 @@ func drawHeader(supportBundleName string) {
ui.Render(title)
}
func drawFooter() {
func drawFooter(archivePath string) {
termWidth, termHeight := ui.TerminalDimensions()
archivePathMsg := widgets.NewParagraph()
archivePathMsg.Text = "Support bundle archive: " + archivePath
archivePathMsg.Border = false
archivePathMsg.TextStyle = ui.NewStyle(ui.ColorWhite, ui.ColorClear, ui.ModifierBold)
archivePathMsg.SetRect(0, termHeight-3, termWidth, termHeight-2)
instructions := widgets.NewParagraph()
instructions.Text = "[q] quit [s] save [↑][↓] scroll"
instructions.Text = "[q] quit [↑][↓] scroll"
instructions.Border = false
left := 0
@@ -126,13 +107,13 @@ func drawFooter() {
bottom := termHeight
instructions.SetRect(left, top, right, bottom)
ui.Render(instructions)
ui.Render(archivePathMsg, instructions)
}
func drawAnalyzersTable(analyzeResults []*analyzerunner.AnalyzeResult) {
termWidth, termHeight := ui.TerminalDimensions()
table.SetRect(0, 3, termWidth/2, termHeight-6)
table.SetRect(0, 3, termWidth/2, termHeight-4)
table.FillRow = true
table.Border = true
table.Rows = [][]string{}
@@ -213,60 +194,3 @@ func drawDetails(analysisResult *analyzerunner.AnalyzeResult) {
message.SetRect(termWidth/2, currentTop, termWidth, currentTop+height)
ui.Render(message)
}
func showSaved(filename string) {
termWidth, termHeight := ui.TerminalDimensions()
savedMessage := widgets.NewParagraph()
savedMessage.Text = fmt.Sprintf("Support Bundle analysis results saved to\n\n%s", filename)
savedMessage.WrapText = true
savedMessage.Border = true
left := termWidth/2 - 20
right := termWidth/2 + 20
top := termHeight/2 - 4
bottom := termHeight/2 + 4
savedMessage.SetRect(left, top, right, bottom)
ui.Render(savedMessage)
isShowingSaved = true
}
func save(analyzeResults []*analyzerunner.AnalyzeResult) (string, error) {
filename := path.Join(util.HomeDir(), fmt.Sprintf("%s-results.txt", "support-bundle"))
_, err := os.Stat(filename)
if err == nil {
os.Remove(filename)
}
results := ""
for _, analyzeResult := range analyzeResults {
result := ""
if analyzeResult.IsPass {
result = "Check PASS\n"
} else if analyzeResult.IsWarn {
result = "Check WARN\n"
} else if analyzeResult.IsFail {
result = "Check FAIL\n"
}
result = result + fmt.Sprintf("Title: %s\n", analyzeResult.Title)
result = result + fmt.Sprintf("Message: %s\n", analyzeResult.Message)
if analyzeResult.URI != "" {
result = result + fmt.Sprintf("URI: %s\n", analyzeResult.URI)
}
result = result + "\n------------\n"
results = results + result
}
if err := ioutil.WriteFile(filename, []byte(results), 0644); err != nil {
return "", errors.Wrap(err, "failed to save preflight results")
}
return filename, nil
}
+1 -1
View File
@@ -64,7 +64,7 @@ For more information on redactors visit https://troubleshoot.sh/docs/redact/
if output == "" {
output = fmt.Sprintf("redacted-support-bundle-%s.tar.gz", time.Now().Format("2006-01-02T15_04_05"))
}
err = collectorResult.ArchiveSupportBundle(bundleDir, output)
err = collectorResult.ArchiveBundle(bundleDir, output)
if err != nil {
return errors.Wrap(err, "failed to create support bundle archive")
}
+72 -5
View File
@@ -6,9 +6,11 @@ import (
"strings"
"github.com/replicatedhq/troubleshoot/cmd/internal/util"
preflightcli "github.com/replicatedhq/troubleshoot/cmd/preflight/cli"
"github.com/replicatedhq/troubleshoot/internal/traces"
"github.com/replicatedhq/troubleshoot/pkg/k8sutil"
"github.com/replicatedhq/troubleshoot/pkg/logger"
"github.com/replicatedhq/troubleshoot/pkg/updater"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"k8s.io/klog/v2"
@@ -18,9 +20,17 @@ func RootCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "support-bundle [urls...]",
Args: cobra.MinimumNArgs(0),
Short: "Generate a support bundle",
Long: `A support bundle is an archive of files, output, metrics and state
from a server that can be used to assist when troubleshooting a Kubernetes cluster.`,
Short: "Generate a support bundle from a Kubernetes cluster or specified sources",
Long: `Generate a support bundle, an archive containing files, output, metrics, and cluster state to aid in troubleshooting Kubernetes clusters.
If no arguments are provided, specs are automatically loaded from the cluster by default.
**Argument Types**:
1. **Secret**: Load specs from a Kubernetes Secret. Format: "secret/namespace-name/secret-name[/data-key]"
2. **ConfigMap**: Load specs from a Kubernetes ConfigMap. Format: "configmap/namespace-name/configmap-name[/data-key]"
3. **File**: Load specs from a local file. Format: Local file path
4. **Standard Input**: Read specs from stdin. Format: "-"
5. **URL**: Load specs from a URL. Supports HTTP and OCI registry URLs.`,
SilenceUsage: true,
PersistentPreRun: func(cmd *cobra.Command, args []string) {
v := viper.GetViper()
@@ -32,10 +42,44 @@ from a server that can be used to assist when troubleshooting a Kubernetes clust
if err := util.StartProfiling(); err != nil {
klog.Errorf("Failed to start profiling: %v", err)
}
// Auto-update support-bundle unless disabled by flag or env
// Only run auto-update for the root support-bundle command, not subcommands
if cmd.Name() == "support-bundle" && !cmd.HasParent() {
envAuto := os.Getenv("TROUBLESHOOT_AUTO_UPDATE")
autoFromEnv := true
if envAuto != "" {
if strings.EqualFold(envAuto, "0") || strings.EqualFold(envAuto, "false") {
autoFromEnv = false
}
}
if v.GetBool("auto-update") && autoFromEnv {
exe, err := os.Executable()
if err == nil {
_ = updater.CheckAndUpdate(cmd.Context(), updater.Options{
BinaryName: "support-bundle",
CurrentPath: exe,
Printf: func(f string, a ...interface{}) { fmt.Fprintf(os.Stderr, f, a...) },
})
}
}
}
},
RunE: func(cmd *cobra.Command, args []string) error {
v := viper.GetViper()
// If there are no locations to load specs from passed in the cli args, we should
// load them from the cluster by setting "load-cluster-specs=true". If the caller
// provided "--load-cluster-specs" cli option, we should respect it.
if len(args) == 0 {
// Check if --load-cluster-specs was set by the cli caller to avoid overriding it
flg := cmd.Flags().Lookup("load-cluster-specs")
if flg != nil && !flg.Changed {
// Load specs from the cluster if no spec(s) is(are) provided in the cli args
v.Set("load-cluster-specs", true)
}
}
closer, err := traces.ConfigureTracing("support-bundle")
if err != nil {
// Do not fail running support-bundle if tracing fails
@@ -46,7 +90,7 @@ from a server that can be used to assist when troubleshooting a Kubernetes clust
err = runTroubleshoot(v, args)
if !v.IsSet("dry-run") && (v.GetBool("debug") || v.IsSet("v")) {
fmt.Printf("\n%s", traces.GetExporterInstance().GetSummary())
fmt.Fprintf(os.Stderr, "\n%s", traces.GetExporterInstance().GetSummary())
}
return err
@@ -62,19 +106,42 @@ from a server that can be used to assist when troubleshooting a Kubernetes clust
cmd.AddCommand(Analyze())
cmd.AddCommand(Redact())
cmd.AddCommand(Diff())
cmd.AddCommand(Schedule())
cmd.AddCommand(UploadCmd())
cmd.AddCommand(util.VersionCmd())
cmd.AddCommand(preflightcli.LintCmd())
cmd.Flags().StringSlice("redactors", []string{}, "names of the additional redactors to use")
cmd.Flags().Bool("redact", true, "enable/disable default redactions")
// Tokenization flags
cmd.Flags().Bool("tokenize", false, "enable intelligent tokenization instead of simple masking (replaces ***HIDDEN*** with ***TOKEN_TYPE_HASH***)")
cmd.Flags().String("redaction-map", "", "generate redaction mapping file at specified path (enables token→original mapping for authorized access)")
cmd.Flags().Bool("encrypt-redaction-map", false, "encrypt the redaction mapping file using AES-256 (requires --redaction-map)")
cmd.Flags().String("token-prefix", "", "custom token prefix format (default: ***TOKEN_%s_%s***)")
cmd.Flags().Bool("verify-tokenization", false, "validation mode: verify tokenization setup without collecting data")
cmd.Flags().String("bundle-id", "", "custom bundle identifier for token correlation (auto-generated if not provided)")
cmd.Flags().Bool("tokenization-stats", false, "include detailed tokenization statistics in output")
cmd.Flags().Bool("interactive", true, "enable/disable interactive mode")
cmd.Flags().Bool("collect-without-permissions", true, "always generate a support bundle, even if it some require additional permissions")
cmd.Flags().StringSliceP("selector", "l", []string{"troubleshoot.sh/kind=support-bundle"}, "selector to filter on for loading additional support bundle specs found in secrets within the cluster")
cmd.Flags().Bool("load-cluster-specs", false, "enable/disable loading additional troubleshoot specs found within the cluster. required when no specs are provided on the command line")
cmd.Flags().Bool("load-cluster-specs", false, "enable/disable loading additional troubleshoot specs found within the cluster. Do not load by default unless no specs are provided in the cli args")
cmd.Flags().String("since-time", "", "force pod logs collectors to return logs after a specific date (RFC3339)")
cmd.Flags().String("since", "", "force pod logs collectors to return logs newer than a relative duration like 5s, 2m, or 3h.")
cmd.Flags().StringP("output", "o", "", "specify the output file path for the support bundle")
cmd.Flags().Bool("debug", false, "enable debug logging. This is equivalent to --v=0")
cmd.Flags().Bool("dry-run", false, "print support bundle spec without collecting anything")
cmd.Flags().Bool("auto-update", true, "enable automatic binary self-update check and install")
// Auto-discovery flags
cmd.Flags().Bool("auto", false, "enable auto-discovery of foundational collectors. When used with YAML specs, adds foundational collectors to YAML collectors. When used alone, collects only foundational data")
cmd.Flags().Bool("include-images", false, "include container image metadata collection when using auto-discovery")
cmd.Flags().Bool("rbac-check", true, "enable RBAC permission checking for auto-discovered collectors")
cmd.Flags().String("discovery-profile", "standard", "auto-discovery profile: minimal, standard, comprehensive, or paranoid")
cmd.Flags().StringSlice("exclude-namespaces", []string{}, "namespaces to exclude from auto-discovery (supports glob patterns)")
cmd.Flags().StringSlice("include-namespaces", []string{}, "namespaces to include in auto-discovery (supports glob patterns). If specified, only these namespaces will be included")
cmd.Flags().Bool("include-system-namespaces", false, "include system namespaces (kube-system, etc.) in auto-discovery")
// hidden in favor of the `insecure-skip-tls-verify` flag
cmd.Flags().Bool("allow-insecure-connections", false, "when set, do not verify TLS certs when retrieving spec and reporting results")
+252 -44
View File
@@ -9,6 +9,8 @@ import (
"os"
"os/signal"
"path/filepath"
"reflect"
"strings"
"sync"
"time"
@@ -26,6 +28,7 @@ import (
"github.com/replicatedhq/troubleshoot/pkg/httputil"
"github.com/replicatedhq/troubleshoot/pkg/k8sutil"
"github.com/replicatedhq/troubleshoot/pkg/loader"
"github.com/replicatedhq/troubleshoot/pkg/redact"
"github.com/replicatedhq/troubleshoot/pkg/supportbundle"
"github.com/replicatedhq/troubleshoot/pkg/types"
"github.com/spf13/viper"
@@ -38,9 +41,6 @@ import (
func runTroubleshoot(v *viper.Viper, args []string) error {
ctx := context.Background()
if !v.GetBool("load-cluster-specs") && len(args) < 1 {
return errors.New("flag load-cluster-specs must be set if no specs are provided on the command line")
}
restConfig, err := k8sutil.GetRESTConfig()
if err != nil {
@@ -57,6 +57,30 @@ func runTroubleshoot(v *viper.Viper, args []string) error {
return err
}
// Validate auto-discovery flags
if err := ValidateAutoDiscoveryFlags(v); err != nil {
return errors.Wrap(err, "invalid auto-discovery configuration")
}
// Validate tokenization flags
if err := ValidateTokenizationFlags(v); err != nil {
return errors.Wrap(err, "invalid tokenization configuration")
}
// Apply auto-discovery if enabled
autoConfig := GetAutoDiscoveryConfig(v)
if autoConfig.Enabled {
mode := GetAutoDiscoveryMode(args, autoConfig.Enabled)
if !v.GetBool("quiet") {
PrintAutoDiscoveryInfo(autoConfig, mode)
}
// Apply auto-discovery to the main bundle
namespace := v.GetString("namespace")
if err := ApplyAutoDiscovery(ctx, client, restConfig, mainBundle, autoConfig, namespace); err != nil {
return errors.Wrap(err, "auto-discovery failed")
}
}
// For --dry-run, we want to print the yaml and exit
if v.GetBool("dry-run") {
k := loader.TroubleshootKinds{
@@ -106,6 +130,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() && !mainBundle.Spec.RunHostCollectorsInPod {
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{})
@@ -170,15 +210,20 @@ func runTroubleshoot(v *viper.Viper, args []string) error {
OutputPath: v.GetString("output"),
Redact: v.GetBool("redact"),
FromCLI: true,
RunHostCollectorsInPod: mainBundle.Spec.RunHostCollectorsInPod,
// Phase 4: Tokenization options
Tokenize: v.GetBool("tokenize"),
RedactionMapPath: v.GetString("redaction-map"),
EncryptRedactionMap: v.GetBool("encrypt-redaction-map"),
TokenPrefix: v.GetString("token-prefix"),
VerifyTokenization: v.GetBool("verify-tokenization"),
BundleID: v.GetString("bundle-id"),
TokenizationStats: v.GetBool("tokenization-stats"),
}
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")
@@ -189,7 +234,7 @@ func runTroubleshoot(v *viper.Viper, args []string) error {
if len(response.AnalyzerResults) > 0 {
if interactive {
if err := showInteractiveResults(mainBundle.Name, response.AnalyzerResults); err != nil {
if err := showInteractiveResults(mainBundle.Name, response.AnalyzerResults, response.ArchivePath); err != nil {
interactive = false
}
} else {
@@ -216,7 +261,7 @@ the %s Admin Console to begin analysis.`
return nil
}
fmt.Printf("\n%s\n", response.ArchivePath)
fmt.Printf("\nA support bundle was generated and saved at %s. Please send this file to your software vendor for support.\n", response.ArchivePath)
return nil
}
@@ -234,47 +279,68 @@ the %s Admin Console to begin analysis.`
// loadSupportBundleSpecsFromURIs loads support bundle specs from URIs
func loadSupportBundleSpecsFromURIs(ctx context.Context, kinds *loader.TroubleshootKinds) error {
remoteRawSpecs := []string{}
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
// TODO: Pass ctx to LoadSupportBundleSpec
rawSpec, err := supportbundle.LoadSupportBundleSpec(s.Spec.Uri)
if err != nil {
// 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
}
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
}
if len(k.SupportBundlesV1Beta2) == 0 {
// add back original spec
moreKinds.SupportBundlesV1Beta2 = append(moreKinds.SupportBundlesV1Beta2, s)
klog.Warningf("no support bundle spec found in URI: %s", s.Spec.Uri)
continue
}
// finally append the uri spec
moreKinds.SupportBundlesV1Beta2 = append(moreKinds.SupportBundlesV1Beta2, k.SupportBundlesV1Beta2...)
}
if len(remoteRawSpecs) == 0 {
return nil
}
kinds.SupportBundlesV1Beta2 = moreKinds.SupportBundlesV1Beta2
moreKinds, err := loader.LoadSpecs(ctx, loader.LoadOptions{
RawSpecs: remoteRawSpecs,
})
if err != nil {
return err
}
kinds.Add(moreKinds)
return nil
}
func loadSpecs(ctx context.Context, args []string, client kubernetes.Interface) (*troubleshootv1beta2.SupportBundle, *troubleshootv1beta2.Redactor, error) {
// Append redactor uris to the args
allArgs := append(args, viper.GetStringSlice("redactors")...)
kinds, err := specs.LoadFromCLIArgs(ctx, client, allArgs, viper.GetViper())
var (
kinds = loader.NewTroubleshootKinds()
vp = viper.GetViper()
redactors = vp.GetStringSlice("redactors")
allArgs = append(args, redactors...)
err error
)
kinds, err = specs.LoadFromCLIArgs(ctx, client, allArgs, vp)
if err != nil {
return nil, nil, err
return nil, nil, errors.Wrap(err, "failed to load specs from CLI args")
}
// 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") {
err := loadSupportBundleSpecsFromURIs(ctx, kinds)
if err != nil {
@@ -283,11 +349,16 @@ func loadSpecs(ctx context.Context, args []string, client kubernetes.Interface)
}
// Check if we have any collectors to run in the troubleshoot specs
// TODO: Do we use the RemoteCollectors anymore?
// Skip this check if auto-discovery is enabled, as collectors will be added later
// Note: RemoteCollectors are still actively used in preflights and host preflights
if len(kinds.CollectorsV1Beta2) == 0 &&
len(kinds.HostCollectorsV1Beta2) == 0 &&
len(kinds.SupportBundlesV1Beta2) == 0 {
return nil, nil, errors.New("no collectors specified to run")
len(kinds.SupportBundlesV1Beta2) == 0 &&
!vp.GetBool("auto") {
return nil, nil, types.NewExitCodeError(
constants.EXIT_CODE_CATCH_ALL,
errors.New("no collectors specified to run. Use --debug and/or -v=2 to see more information"),
)
}
// Merge specs
@@ -302,10 +373,37 @@ func loadSpecs(ctx context.Context, args []string, client kubernetes.Interface)
Name: "merged-support-bundle-spec",
},
}
// If auto-discovery is enabled and no support bundle specs were loaded,
// create a minimal default support bundle spec for auto-discovery to work with
if vp.GetBool("auto") && len(kinds.SupportBundlesV1Beta2) == 0 {
defaultSupportBundle := troubleshootv1beta2.SupportBundle{
TypeMeta: metav1.TypeMeta{
APIVersion: "troubleshoot.replicated.com/v1beta2",
Kind: "SupportBundle",
},
ObjectMeta: metav1.ObjectMeta{
Name: "auto-discovery-default",
},
Spec: troubleshootv1beta2.SupportBundleSpec{
Collectors: []*troubleshootv1beta2.Collect{}, // Empty collectors - will be populated by auto-discovery
},
}
kinds.SupportBundlesV1Beta2 = append(kinds.SupportBundlesV1Beta2, defaultSupportBundle)
klog.V(2).Info("Created default support bundle spec for auto-discovery")
}
var enableRunHostCollectorsInPod bool
for _, sb := range kinds.SupportBundlesV1Beta2 {
sb := sb
mainBundle = supportbundle.ConcatSpec(mainBundle, &sb)
//check if sb has metadata and if it has RunHostCollectorsInPod set to true
if !reflect.DeepEqual(sb.ObjectMeta, metav1.ObjectMeta{}) && sb.Spec.RunHostCollectorsInPod {
enableRunHostCollectorsInPod = sb.Spec.RunHostCollectorsInPod
}
}
mainBundle.Spec.RunHostCollectorsInPod = enableRunHostCollectorsInPod
for _, c := range kinds.CollectorsV1Beta2 {
mainBundle.Spec.Collectors = util.Append(mainBundle.Spec.Collectors, c.Spec.Collectors)
@@ -315,8 +413,9 @@ func loadSpecs(ctx context.Context, args []string, client kubernetes.Interface)
mainBundle.Spec.HostCollectors = util.Append(mainBundle.Spec.HostCollectors, hc.Spec.Collectors)
}
if !(len(mainBundle.Spec.HostCollectors) > 0 && len(mainBundle.Spec.Collectors) == 0) {
// Always add default collectors unless we only have host collectors
// Don't add default collectors if auto-discovery is enabled, as auto-discovery will add them
if !(len(mainBundle.Spec.HostCollectors) > 0 && len(mainBundle.Spec.Collectors) == 0) && !vp.GetBool("auto") {
// Always add default collectors unless we only have host collectors or auto-discovery is enabled
// 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
@@ -333,7 +432,7 @@ func loadSpecs(ctx context.Context, args []string, client kubernetes.Interface)
additionalRedactors := &troubleshootv1beta2.Redactor{
TypeMeta: metav1.TypeMeta{
APIVersion: "troubleshoot.sh/v1beta2",
APIVersion: "troubleshoot.replicated.com/v1beta2",
Kind: "Redactor",
},
ObjectMeta: metav1.ObjectMeta{
@@ -344,6 +443,12 @@ func loadSpecs(ctx context.Context, args []string, client kubernetes.Interface)
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
}
@@ -396,3 +501,106 @@ func (a *analysisOutput) FormattedAnalysisOutput() (outputJson string, err error
}
return string(formatted), nil
}
// ValidateTokenizationFlags validates tokenization flag combinations
func ValidateTokenizationFlags(v *viper.Viper) error {
// Verify tokenization mode early (before collection starts)
if v.GetBool("verify-tokenization") {
if err := VerifyTokenizationSetup(v); err != nil {
return errors.Wrap(err, "tokenization verification failed")
}
fmt.Println("✅ Tokenization verification passed")
os.Exit(0) // Exit after verification
}
// Encryption requires redaction map
if v.GetBool("encrypt-redaction-map") && v.GetString("redaction-map") == "" {
return errors.New("--encrypt-redaction-map requires --redaction-map to be specified")
}
// Redaction map requires tokenization or redaction to be enabled
if v.GetString("redaction-map") != "" {
if !v.GetBool("tokenize") && !v.GetBool("redact") {
return errors.New("--redaction-map requires either --tokenize or --redact to be enabled")
}
}
// Custom token prefix requires tokenization
if v.GetString("token-prefix") != "" && !v.GetBool("tokenize") {
return errors.New("--token-prefix requires --tokenize to be enabled")
}
// Bundle ID requires tokenization
if v.GetString("bundle-id") != "" && !v.GetBool("tokenize") {
return errors.New("--bundle-id requires --tokenize to be enabled")
}
// Tokenization stats requires tokenization
if v.GetBool("tokenization-stats") && !v.GetBool("tokenize") {
return errors.New("--tokenization-stats requires --tokenize to be enabled")
}
return nil
}
// VerifyTokenizationSetup verifies tokenization configuration without collecting data
func VerifyTokenizationSetup(v *viper.Viper) error {
fmt.Println("🔍 Verifying tokenization setup...")
// Test 1: Environment variable check
if v.GetBool("tokenize") {
os.Setenv("TROUBLESHOOT_TOKENIZATION", "true")
defer os.Unsetenv("TROUBLESHOOT_TOKENIZATION")
}
// Test 2: Tokenizer initialization
redact.ResetGlobalTokenizer()
tokenizer := redact.GetGlobalTokenizer()
if v.GetBool("tokenize") && !tokenizer.IsEnabled() {
return errors.New("tokenizer is not enabled despite --tokenize flag")
}
if !v.GetBool("tokenize") && tokenizer.IsEnabled() {
return errors.New("tokenizer is enabled despite --tokenize flag being false")
}
fmt.Printf(" ✅ Tokenizer state: %v\n", tokenizer.IsEnabled())
// Test 3: Token generation
if tokenizer.IsEnabled() {
testToken := tokenizer.TokenizeValue("test-secret", "verification")
if !tokenizer.ValidateToken(testToken) {
return errors.Errorf("generated test token is invalid: %s", testToken)
}
fmt.Printf(" ✅ Test token generated: %s\n", testToken)
}
// Test 4: Custom token prefix validation
if customPrefix := v.GetString("token-prefix"); customPrefix != "" {
if !strings.Contains(customPrefix, "%s") {
return errors.Errorf("custom token prefix must contain %%s placeholders: %s", customPrefix)
}
fmt.Printf(" ✅ Custom token prefix validated: %s\n", customPrefix)
}
// Test 5: Redaction map path validation
if mapPath := v.GetString("redaction-map"); mapPath != "" {
// Check if directory exists
dir := filepath.Dir(mapPath)
if _, err := os.Stat(dir); os.IsNotExist(err) {
return errors.Errorf("redaction map directory does not exist: %s", dir)
}
fmt.Printf(" ✅ Redaction map path validated: %s\n", mapPath)
// Test file creation (and cleanup)
testFile := mapPath + ".test"
if err := os.WriteFile(testFile, []byte("test"), 0600); err != nil {
return errors.Errorf("cannot create redaction map file: %v", err)
}
os.Remove(testFile)
fmt.Printf(" ✅ File creation permissions verified\n")
}
return nil
}
+167 -7
View File
@@ -18,7 +18,8 @@ import (
testclient "k8s.io/client-go/kubernetes/fake"
)
var orig = `
func templSpec() string {
return `
apiVersion: troubleshoot.sh/v1beta2
kind: SupportBundle
metadata:
@@ -30,6 +31,7 @@ spec:
name: kube-root-ca.crt
namespace: default
`
}
func Test_loadSupportBundleSpecsFromURIs(t *testing.T) {
// Run a webserver to serve the spec
@@ -45,7 +47,7 @@ spec:
}))
defer srv.Close()
orig := strings.ReplaceAll(orig, "$MY_URI", srv.URL)
orig := strings.ReplaceAll(templSpec(), "$MY_URI", srv.URL)
ctx := context.Background()
kinds, err := loader.LoadSpecs(ctx, loader.LoadOptions{RawSpec: orig})
@@ -57,8 +59,73 @@ spec:
err = loadSupportBundleSpecsFromURIs(ctx, kinds)
require.NoError(t, err)
require.Len(t, kinds.SupportBundlesV1Beta2, 2)
assert.NotNil(t, kinds.SupportBundlesV1Beta2[1].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) {
@@ -69,14 +136,15 @@ func Test_loadSupportBundleSpecsFromURIs_TimeoutError(t *testing.T) {
ctx := context.Background()
kinds, err := loader.LoadSpecs(ctx, loader.LoadOptions{
RawSpec: strings.ReplaceAll(orig, "$MY_URI", srv.URL),
RawSpec: strings.ReplaceAll(templSpec(), "$MY_URI", srv.URL),
})
require.NoError(t, err)
// Set the timeout on the http client to 10ms
// Set the timeout on the http client to 500ms
// The server sleeps for 2 seconds, so this should still timeout
// supportbundle.LoadSupportBundleSpec does not yet use the context
before := httputil.GetHttpClient().Timeout
httputil.GetHttpClient().Timeout = 10 * time.Millisecond
httputil.GetHttpClient().Timeout = 500 * time.Millisecond
defer func() {
// Reinstate the original timeout. Its a global var so we need to reset it
httputil.GetHttpClient().Timeout = before
@@ -276,3 +344,95 @@ 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
}
func Test_loadInvalidURISpec(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(`invalid spec`))
}))
defer srv.Close()
// update URI spec with the server URL
orig := strings.ReplaceAll(templSpec(), "$MY_URI", srv.URL)
specFile := testutils.ServeFromFilePath(t, orig)
ctx := context.Background()
client := testclient.NewSimpleClientset()
sb, _, err := loadSpecs(ctx, []string{specFile}, client)
require.NoError(t, err)
assert.Len(t, sb.Spec.Collectors, 3) // default + clusterInfo + clusterResources
assert.NotNil(t, sb.Spec.Collectors[0].ConfigMap) // come from the original spec
}
+11
View File
@@ -0,0 +1,11 @@
package cli
import (
"github.com/replicatedhq/troubleshoot/pkg/schedule"
"github.com/spf13/cobra"
)
// Schedule returns the schedule command for managing scheduled support bundle jobs
func Schedule() *cobra.Command {
return schedule.CLI()
}
+56
View File
@@ -0,0 +1,56 @@
package cli
import (
"os"
"github.com/pkg/errors"
"github.com/replicatedhq/troubleshoot/pkg/supportbundle"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
func UploadCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "upload [bundle-file]",
Args: cobra.ExactArgs(1),
Short: "Upload a support bundle to replicated.app",
Long: `Upload a support bundle to replicated.app for analysis and troubleshooting.
This command automatically extracts the license ID and app slug from the bundle if not provided.
Examples:
# Auto-detect license and app from bundle
support-bundle upload bundle.tar.gz
# Specify license ID explicitly
support-bundle upload bundle.tar.gz --license-id YOUR_LICENSE_ID
# Specify both license and app
support-bundle upload bundle.tar.gz --license-id YOUR_LICENSE_ID --app-slug my-app`,
RunE: func(cmd *cobra.Command, args []string) error {
v := viper.GetViper()
bundlePath := args[0]
// Check if bundle file exists
if _, err := os.Stat(bundlePath); os.IsNotExist(err) {
return errors.Errorf("bundle file does not exist: %s", bundlePath)
}
// Get upload parameters
licenseID := v.GetString("license-id")
appSlug := v.GetString("app-slug")
// Use auto-detection for uploads
if err := supportbundle.UploadBundleAutoDetect(bundlePath, licenseID, appSlug); err != nil {
return errors.Wrap(err, "upload failed")
}
return nil
},
}
cmd.Flags().String("license-id", "", "license ID for authentication (auto-detected from bundle if not provided)")
cmd.Flags().String("app-slug", "", "application slug (auto-detected from bundle if not provided)")
return cmd
}
@@ -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.19.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
@@ -413,6 +417,12 @@ spec:
type: string
podCapacity:
type: string
resourceAllocatable:
type: string
resourceCapacity:
type: string
resourceName:
type: string
selector:
properties:
matchLabel:
@@ -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.19.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.19.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
@@ -413,6 +417,12 @@ spec:
type: string
podCapacity:
type: string
resourceAllocatable:
type: string
resourceCapacity:
type: string
resourceName:
type: string
selector:
properties:
matchLabel:
@@ -836,10 +846,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 +870,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 +892,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.19.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.19.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
@@ -444,6 +448,12 @@ spec:
type: string
podCapacity:
type: string
resourceAllocatable:
type: string
resourceCapacity:
type: string
resourceName:
type: string
selector:
properties:
matchLabel:
@@ -867,10 +877,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 +901,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 +923,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:
+508 -10
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.19.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
@@ -137,6 +141,61 @@ spec:
required:
- outcomes
type: object
clusterContainerStatuses:
properties:
annotations:
additionalProperties:
type: string
type: object
checkName:
type: string
exclude:
type: BoolString
namespaces:
items:
type: string
type: array
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
restartCount:
format: int32
type: integer
strict:
type: BoolString
required:
- outcomes
- restartCount
type: object
clusterPodStatuses:
properties:
annotations:
@@ -669,6 +728,55 @@ spec:
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:
@@ -1041,6 +1149,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:
@@ -1053,10 +1221,10 @@ spec:
type: BoolString
filters:
properties:
architecture:
type: string
cpuAllocatable:
type: string
cpuArchitecture:
type: string
cpuCapacity:
type: string
ephemeralStorageAllocatable:
@@ -1071,13 +1239,77 @@ spec:
type: string
podCapacity:
type: string
resourceAllocatable:
type: string
resourceCapacity:
type: string
resourceName:
type: string
selector:
properties:
matchExpressions:
items:
description: |-
A label selector requirement is a selector that contains values, a key, and an operator that
relates the key and values.
properties:
key:
description: key is the label key that the
selector applies to.
type: string
operator:
description: |-
operator represents a key's relationship to a set of values.
Valid operators are In, NotIn, Exists and DoesNotExist.
type: string
values:
description: |-
values is an array of string values. If the operator is In or NotIn,
the values array must be non-empty. If the operator is Exists or DoesNotExist,
the values array must be empty. This array is replaced during a strategic
merge patch.
items:
type: string
type: array
x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
matchLabel:
additionalProperties:
type: string
type: object
type: object
taint:
description: |-
The node this Taint is attached to has the "effect" on
any pod that does not tolerate the Taint.
properties:
effect:
description: |-
Required. The effect of the taint on pods
that do not tolerate the taint.
Valid effects are NoSchedule, PreferNoSchedule and NoExecute.
type: string
key:
description: Required. The taint key to be applied
to a node.
type: string
timeAdded:
description: TimeAdded represents the time at which
the taint was added.
format: date-time
type: string
value:
description: The taint value corresponding to the
taint key.
type: string
required:
- effect
- key
type: object
type: object
outcomes:
items:
@@ -2235,6 +2467,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:
@@ -2333,6 +2676,55 @@ spec:
required:
- outcomes
type: object
networkNamespaceConnectivity:
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
subnetAvailable:
properties:
annotations:
@@ -2382,6 +2774,110 @@ spec:
required:
- outcomes
type: object
subnetContainsIP:
properties:
annotations:
additionalProperties:
type: string
type: object
checkName:
type: string
cidr:
type: string
collectorName:
type: string
exclude:
type: BoolString
ip:
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:
- cidr
- ip
- outcomes
type: object
sysctl:
properties:
annotations:
additionalProperties:
type: string
type: object
checkName:
type: string
collectorName:
type: string
exclude:
type: BoolString
outcomes:
items:
properties:
fail:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
pass:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
warn:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
type: object
type: array
strict:
type: BoolString
required:
- outcomes
type: object
systemPackages:
properties:
annotations:
@@ -2739,6 +3235,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
+475 -49
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.19.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:
@@ -682,6 +797,55 @@ spec:
required:
- outcomes
type: object
networkNamespaceConnectivity:
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
subnetAvailable:
properties:
annotations:
@@ -731,6 +895,110 @@ spec:
required:
- outcomes
type: object
subnetContainsIP:
properties:
annotations:
additionalProperties:
type: string
type: object
checkName:
type: string
cidr:
type: string
collectorName:
type: string
exclude:
type: BoolString
ip:
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:
- cidr
- ip
- outcomes
type: object
sysctl:
properties:
annotations:
additionalProperties:
type: string
type: object
checkName:
type: string
collectorName:
type: string
exclude:
type: BoolString
outcomes:
items:
properties:
fail:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
pass:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
warn:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
type: object
type: array
strict:
type: BoolString
required:
- outcomes
type: object
systemPackages:
properties:
annotations:
@@ -1125,6 +1393,15 @@ spec:
required:
- paths
type: object
cgroups:
properties:
collectorName:
type: string
exclude:
type: BoolString
mountPoint:
type: string
type: object
copy:
properties:
collectorName:
@@ -1154,10 +1431,23 @@ spec:
required:
- path
type: object
dns:
properties:
collectorName:
type: string
exclude:
type: BoolString
hostnames:
items:
type: string
type: array
required:
- hostnames
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 +1455,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,18 +1493,22 @@ 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
runTime:
description: |-
Limit runtime. The test will run until it completes the configured I/O workload or until it
has run for this specified amount of time, whichever occurs first. When the unit is omitted,
the value is interpreted in seconds. Defaults to 120 seconds. Set to "0" to disable.
type: string
sync:
description: Whether to call sync on the file after each
write. Does not apply to background IOPS task.
@@ -1260,11 +1553,34 @@ spec:
type: object
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.
proxy:
type: string
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
tls:
properties:
cacert:
type: string
clientCert:
type: string
clientKey:
type: string
secret:
properties:
name:
type: string
namespace:
type: string
required:
- name
- namespace
type: object
skipVerify:
type: boolean
type: object
url:
type: string
required:
@@ -1280,11 +1596,34 @@ spec:
type: object
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.
proxy:
type: string
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
tls:
properties:
cacert:
type: string
clientCert:
type: string
clientKey:
type: string
secret:
properties:
name:
type: string
namespace:
type: string
required:
- name
- namespace
type: object
skipVerify:
type: boolean
type: object
url:
type: string
required:
@@ -1300,11 +1639,34 @@ spec:
type: object
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.
proxy:
type: string
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
tls:
properties:
cacert:
type: string
clientCert:
type: string
clientKey:
type: string
secret:
properties:
name:
type: string
namespace:
type: string
required:
- name
- namespace
type: object
skipVerify:
type: boolean
type: object
url:
type: string
required:
@@ -1337,6 +1699,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:
@@ -1358,6 +1756,25 @@ spec:
exclude:
type: BoolString
type: object
networkNamespaceConnectivity:
properties:
collectorName:
type: string
exclude:
type: BoolString
fromCIDR:
type: string
port:
type: integer
timeout:
type: string
toCIDR:
type: string
required:
- fromCIDR
- port
- toCIDR
type: object
run:
properties:
args:
@@ -1406,6 +1823,13 @@ spec:
- CIDRRangeAlloc
- desiredCIDR
type: object
sysctl:
properties:
collectorName:
type: string
exclude:
type: BoolString
type: object
systemPackages:
properties:
amzn:
@@ -1561,6 +1985,8 @@ spec:
type: object
type: object
type: array
uri:
type: string
type: object
status:
description: HostCollectorStatus defines the observed state of HostCollector
+596 -91
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.19.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:
@@ -682,6 +797,55 @@ spec:
required:
- outcomes
type: object
networkNamespaceConnectivity:
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
subnetAvailable:
properties:
annotations:
@@ -731,6 +895,110 @@ spec:
required:
- outcomes
type: object
subnetContainsIP:
properties:
annotations:
additionalProperties:
type: string
type: object
checkName:
type: string
cidr:
type: string
collectorName:
type: string
exclude:
type: BoolString
ip:
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:
- cidr
- ip
- outcomes
type: object
sysctl:
properties:
annotations:
additionalProperties:
type: string
type: object
checkName:
type: string
collectorName:
type: string
exclude:
type: BoolString
outcomes:
items:
properties:
fail:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
pass:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
warn:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
type: object
type: array
strict:
type: BoolString
required:
- outcomes
type: object
systemPackages:
properties:
annotations:
@@ -1125,6 +1393,15 @@ spec:
required:
- paths
type: object
cgroups:
properties:
collectorName:
type: string
exclude:
type: BoolString
mountPoint:
type: string
type: object
copy:
properties:
collectorName:
@@ -1154,10 +1431,23 @@ spec:
required:
- path
type: object
dns:
properties:
collectorName:
type: string
exclude:
type: BoolString
hostnames:
items:
type: string
type: array
required:
- hostnames
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 +1455,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,18 +1493,22 @@ 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
runTime:
description: |-
Limit runtime. The test will run until it completes the configured I/O workload or until it
has run for this specified amount of time, whichever occurs first. When the unit is omitted,
the value is interpreted in seconds. Defaults to 120 seconds. Set to "0" to disable.
type: string
sync:
description: Whether to call sync on the file after each
write. Does not apply to background IOPS task.
@@ -1260,11 +1553,34 @@ spec:
type: object
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.
proxy:
type: string
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
tls:
properties:
cacert:
type: string
clientCert:
type: string
clientKey:
type: string
secret:
properties:
name:
type: string
namespace:
type: string
required:
- name
- namespace
type: object
skipVerify:
type: boolean
type: object
url:
type: string
required:
@@ -1280,11 +1596,34 @@ spec:
type: object
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.
proxy:
type: string
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
tls:
properties:
cacert:
type: string
clientCert:
type: string
clientKey:
type: string
secret:
properties:
name:
type: string
namespace:
type: string
required:
- name
- namespace
type: object
skipVerify:
type: boolean
type: object
url:
type: string
required:
@@ -1300,11 +1639,34 @@ spec:
type: object
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.
proxy:
type: string
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
tls:
properties:
cacert:
type: string
clientCert:
type: string
clientKey:
type: string
secret:
properties:
name:
type: string
namespace:
type: string
required:
- name
- namespace
type: object
skipVerify:
type: boolean
type: object
url:
type: string
required:
@@ -1337,6 +1699,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:
@@ -1358,6 +1756,25 @@ spec:
exclude:
type: BoolString
type: object
networkNamespaceConnectivity:
properties:
collectorName:
type: string
exclude:
type: BoolString
fromCIDR:
type: string
port:
type: integer
timeout:
type: string
toCIDR:
type: string
required:
- fromCIDR
- port
- toCIDR
type: object
run:
properties:
args:
@@ -1406,6 +1823,13 @@ spec:
- CIDRRangeAlloc
- desiredCIDR
type: object
sysctl:
properties:
collectorName:
type: string
exclude:
type: BoolString
type: object
systemPackages:
properties:
amzn:
@@ -1604,44 +2028,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
@@ -1653,18 +2076,22 @@ 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
runTime:
description: |-
Limit runtime. The test will run until it completes the configured I/O workload or until it
has run for this specified amount of time, whichever occurs first. When the unit is omitted,
the value is interpreted in seconds. Defaults to 120 seconds. Set to "0" to disable.
type: string
sync:
description: Whether to call sync on the file after each
write. Does not apply to background IOPS task.
@@ -1681,6 +2108,13 @@ spec:
- backgroundWriteIOPSJobs
- enableBackgroundIOPS
type: object
hostOS:
properties:
collectorName:
type: string
exclude:
type: BoolString
type: object
hostServices:
properties:
collectorName:
@@ -1702,11 +2136,34 @@ spec:
type: object
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.
proxy:
type: string
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
tls:
properties:
cacert:
type: string
clientCert:
type: string
clientKey:
type: string
secret:
properties:
name:
type: string
namespace:
type: string
required:
- name
- namespace
type: object
skipVerify:
type: boolean
type: object
url:
type: string
required:
@@ -1722,11 +2179,34 @@ spec:
type: object
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.
proxy:
type: string
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
tls:
properties:
cacert:
type: string
clientCert:
type: string
clientKey:
type: string
secret:
properties:
name:
type: string
namespace:
type: string
required:
- name
- namespace
type: object
skipVerify:
type: boolean
type: object
url:
type: string
required:
@@ -1742,11 +2222,34 @@ spec:
type: object
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.
proxy:
type: string
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
tls:
properties:
cacert:
type: string
clientCert:
type: string
clientKey:
type: string
secret:
properties:
name:
type: string
namespace:
type: string
required:
- name
- namespace
type: object
skipVerify:
type: boolean
type: object
url:
type: string
required:
@@ -1878,6 +2381,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

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