From e9fac00516bcb78b040c3f2ffd2e6a84dc3e4464 Mon Sep 17 00:00:00 2001 From: Chase Hainey <94016231+chasehainey@users.noreply.github.com> Date: Mon, 27 Mar 2023 09:06:27 -0600 Subject: [PATCH] feat: Add mssql collector and analyser (#990) * Adds MSSQL collector based on Postgres collector * Adds tests for MSSQL based on the tests for Postgres * Adds analyzer * Adds MS SQL Server example * Assures MS SQL tests pass * Aligns naming and adds to API * Corrects names that weren't updated * Updates text on sample * Corrects typo * Makes troubleshoot aware of mssql * Uses Hashicorp version library for SQL Server versions * Resyncs generated file * Cleaning up the workspace. * Updates schemas per PR feedback * Unit Tests. * fix: address runtime error of nil pointer when concatenating preflight specs (#998) fix: address runtime error of nil pointer when concatenating preflight spec with hostpreflight spec in preflight run.go * chore: chore: update binaries used to build manifests and k8s (#997) - client-gen version from v0.22.0 to v0.26.1 - controller-gen version from v0.7.0 to v0.11.2 - k8s pacth from 1.26.0 to 1.26.1 * Deduplication for In-Cluster Collectors (#972) * adding dedup for in cluster collectors * add tests * return collector as is whenever marshalling to json fails --------- Co-authored-by: Evans Mungai * refactor: keep support bundle concat logic to be consistent with Preflight concat (#1002) * refactor: keep support bundle concat logic to be consistent with Preflight * test: add tests for support bundle spec concat function * chore: Refactor in cluster analysers (#999) Have all in-cluster analysers implement the same interface. This will help with the implementation of code that requires making calls to all analysers Fixes #995 * feat: Record summary of execution times of support bundle operations (collect/redact/analyse) (#935) When running a support bundle, we want to know how long each operation (collect, redact, analyze) takes. This commit adds a new trace exporter that records the start and end times of each operation, and then prints a summary of the execution. The summary is also stored in the support bundle. Related to #923 * chore(deps): bump sigs.k8s.io/controller-runtime from 0.14.2 to 0.14.4 (#1006) Bumps [sigs.k8s.io/controller-runtime](https://github.com/kubernetes-sigs/controller-runtime) from 0.14.2 to 0.14.4. - [Release notes](https://github.com/kubernetes-sigs/controller-runtime/releases) - [Changelog](https://github.com/kubernetes-sigs/controller-runtime/blob/master/RELEASE.md) - [Commits](https://github.com/kubernetes-sigs/controller-runtime/compare/v0.14.2...v0.14.4) --- updated-dependencies: - dependency-name: sigs.k8s.io/controller-runtime dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump github.com/shirou/gopsutil/v3 from 3.22.12 to 3.23.1 (#1007) Bumps [github.com/shirou/gopsutil/v3](https://github.com/shirou/gopsutil) from 3.22.12 to 3.23.1. - [Release notes](https://github.com/shirou/gopsutil/releases) - [Commits](https://github.com/shirou/gopsutil/compare/v3.22.12...v3.23.1) --- updated-dependencies: - dependency-name: github.com/shirou/gopsutil/v3 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore: Don't hardcode /bin/bash (#1011) Bash is not always installed in /bin/bash. Mitigate that by relying on bash being in PATH. * chore: Don't print which error in Makefile (#1012) The which binary is used to detect if client-gen is installed, and if it's not, the Makefile will install it. The initial detection prints an error if it's not found. This is misleading, as it is actually an expected situation. * chore: remove unused code (#1013) Remove code snippets that are not used across the codebase. * remove PR label enforcement workflow (#1015) * chore(deps): bump go.opentelemetry.io/otel/sdk from 1.11.2 to 1.13.0 (#1020) Bumps [go.opentelemetry.io/otel/sdk](https://github.com/open-telemetry/opentelemetry-go) from 1.11.2 to 1.13.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.11.2...v1.13.0) --- updated-dependencies: - dependency-name: go.opentelemetry.io/otel/sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump golang.org/x/text from 0.6.0 to 0.7.0 (#1017) Bumps [golang.org/x/text](https://github.com/golang/text) from 0.6.0 to 0.7.0. - [Release notes](https://github.com/golang/text/releases) - [Commits](https://github.com/golang/text/compare/v0.6.0...v0.7.0) --- updated-dependencies: - dependency-name: golang.org/x/text dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump github.com/jackc/pgx/v5 from 5.2.0 to 5.3.0 (#1018) Bumps [github.com/jackc/pgx/v5](https://github.com/jackc/pgx) from 5.2.0 to 5.3.0. - [Release notes](https://github.com/jackc/pgx/releases) - [Changelog](https://github.com/jackc/pgx/blob/master/CHANGELOG.md) - [Commits](https://github.com/jackc/pgx/compare/v5.2.0...v5.3.0) --- updated-dependencies: - dependency-name: github.com/jackc/pgx/v5 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump github.com/hashicorp/go-getter from 1.6.2 to 1.7.0 (#1019) Bumps [github.com/hashicorp/go-getter](https://github.com/hashicorp/go-getter) from 1.6.2 to 1.7.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.6.2...v1.7.0) --- updated-dependencies: - dependency-name: github.com/hashicorp/go-getter dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * feat(support-bundle): print progress in debug non-interactive mode (#1010) Currently, there's no debug logs whatsoever when running a command like troubleshoot --debug --interactive=false Tackle this by printing similar log statements as presented in interactive mode to the debug logger. Refactor the code a bit so there's no need for a dedicated finished channel and to exit the goroutines properly. Co-authored-by: Evans Mungai * chore(deps): bump github.com/containerd/containerd from 1.6.12 to 1.6.18 (#1021) Bumps [github.com/containerd/containerd](https://github.com/containerd/containerd) from 1.6.12 to 1.6.18. - [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.6.12...v1.6.18) --- updated-dependencies: - dependency-name: github.com/containerd/containerd dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump golang.org/x/net from 0.6.0 to 0.7.0 (#1025) Bumps [golang.org/x/net](https://github.com/golang/net) from 0.6.0 to 0.7.0. - [Release notes](https://github.com/golang/net/releases) - [Commits](https://github.com/golang/net/compare/v0.6.0...v0.7.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump github.com/containers/image/v5 from 5.24.0 to 5.24.1 (#1026) Bumps [github.com/containers/image/v5](https://github.com/containers/image) from 5.24.0 to 5.24.1. - [Release notes](https://github.com/containers/image/releases) - [Commits](https://github.com/containers/image/compare/v5.24.0...v5.24.1) --- updated-dependencies: - dependency-name: github.com/containers/image/v5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Update README to add link for the docs (#1022) Co-authored-by: Evans Mungai * feat: use klog as the default logging library (#1008) * chore(deps): bump github.com/shirou/gopsutil/v3 from 3.23.1 to 3.23.2 (#1043) Bumps [github.com/shirou/gopsutil/v3](https://github.com/shirou/gopsutil) from 3.23.1 to 3.23.2. - [Release notes](https://github.com/shirou/gopsutil/releases) - [Commits](https://github.com/shirou/gopsutil/compare/v3.23.1...v3.23.2) --- updated-dependencies: - dependency-name: github.com/shirou/gopsutil/v3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump go.opentelemetry.io/otel from 1.13.0 to 1.14.0 (#1040) Bumps [go.opentelemetry.io/otel](https://github.com/open-telemetry/opentelemetry-go) from 1.13.0 to 1.14.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.13.0...v1.14.0) --- updated-dependencies: - dependency-name: go.opentelemetry.io/otel dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump github.com/containers/image/v5 from 5.24.1 to 5.24.2 (#1038) Bumps [github.com/containers/image/v5](https://github.com/containers/image) from 5.24.1 to 5.24.2. - [Release notes](https://github.com/containers/image/releases) - [Commits](https://github.com/containers/image/compare/v5.24.1...v5.24.2) --- updated-dependencies: - dependency-name: github.com/containers/image/v5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * feat: support for rhel 9 variants (rhel, centos, ol, rocky) (#1045) * fix: Use namespace from the collector spec for Ceph (#1042) use namespace from the collector spec for ceph * chore(deps): bump go.opentelemetry.io/otel/sdk from 1.13.0 to 1.14.0 (#1039) Bumps [go.opentelemetry.io/otel/sdk](https://github.com/open-telemetry/opentelemetry-go) from 1.13.0 to 1.14.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.13.0...v1.14.0) --- updated-dependencies: - dependency-name: go.opentelemetry.io/otel/sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Collector/Analyzer - Subnet Available (#1004) * Adding a new Subnet Available Collector and Analyzer, used to check if a subnet is available for use on a K8s node. * chore(deps): bump k8s.io/apimachinery from 0.26.1 to 0.26.2 (#1050) Bumps [k8s.io/apimachinery](https://github.com/kubernetes/apimachinery) from 0.26.1 to 0.26.2. - [Release notes](https://github.com/kubernetes/apimachinery/releases) - [Commits](https://github.com/kubernetes/apimachinery/compare/v0.26.1...v0.26.2) --- updated-dependencies: - dependency-name: k8s.io/apimachinery dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump sigs.k8s.io/controller-runtime from 0.14.4 to 0.14.5 (#1048) Bumps [sigs.k8s.io/controller-runtime](https://github.com/kubernetes-sigs/controller-runtime) from 0.14.4 to 0.14.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.14.4...v0.14.5) --- updated-dependencies: - dependency-name: sigs.k8s.io/controller-runtime dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * dont run tests on draft PRs (#966) Co-authored-by: Xav Paice * chore(deps): bump k8s.io/klog/v2 from 2.90.0 to 2.90.1 (#1052) Bumps [k8s.io/klog/v2](https://github.com/kubernetes/klog) from 2.90.0 to 2.90.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.90.0...v2.90.1) --- updated-dependencies: - dependency-name: k8s.io/klog/v2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump k8s.io/cli-runtime from 0.26.1 to 0.26.2 (#1049) Bumps [k8s.io/cli-runtime](https://github.com/kubernetes/cli-runtime) from 0.26.1 to 0.26.2. - [Release notes](https://github.com/kubernetes/cli-runtime/releases) - [Commits](https://github.com/kubernetes/cli-runtime/compare/v0.26.1...v0.26.2) --- updated-dependencies: - dependency-name: k8s.io/cli-runtime dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump k8s.io/apiextensions-apiserver from 0.26.1 to 0.26.2 (#1051) * chore(deps): bump k8s.io/apiextensions-apiserver from 0.26.1 to 0.26.2 Bumps [k8s.io/apiextensions-apiserver](https://github.com/kubernetes/apiextensions-apiserver) from 0.26.1 to 0.26.2. - [Release notes](https://github.com/kubernetes/apiextensions-apiserver/releases) - [Commits](https://github.com/kubernetes/apiextensions-apiserver/compare/v0.26.1...v0.26.2) --- updated-dependencies: - dependency-name: k8s.io/apiextensions-apiserver dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * chore(deps): bump k8s.io/klog/v2 from 2.90.0 to 2.90.1 (#1052) Bumps [k8s.io/klog/v2](https://github.com/kubernetes/klog) from 2.90.0 to 2.90.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.90.0...v2.90.1) --- updated-dependencies: - dependency-name: k8s.io/klog/v2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump k8s.io/cli-runtime from 0.26.1 to 0.26.2 (#1049) Bumps [k8s.io/cli-runtime](https://github.com/kubernetes/cli-runtime) from 0.26.1 to 0.26.2. - [Release notes](https://github.com/kubernetes/cli-runtime/releases) - [Commits](https://github.com/kubernetes/cli-runtime/compare/v0.26.1...v0.26.2) --- updated-dependencies: - dependency-name: k8s.io/cli-runtime dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump k8s.io/apiextensions-apiserver from 0.26.1 to 0.26.2 Bumps [k8s.io/apiextensions-apiserver](https://github.com/kubernetes/apiextensions-apiserver) from 0.26.1 to 0.26.2. - [Release notes](https://github.com/kubernetes/apiextensions-apiserver/releases) - [Commits](https://github.com/kubernetes/apiextensions-apiserver/compare/v0.26.1...v0.26.2) --- updated-dependencies: - dependency-name: k8s.io/apiextensions-apiserver dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Update go.sum --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Evans Mungai * Adds MSSQL collector based on Postgres collector * Missed a merge conflict. * More merge conflicts fixed. * Ran go mod tidy. * Fixed the function name return. --------- Signed-off-by: dependabot[bot] Co-authored-by: Chuck D'Antonio Co-authored-by: yunju.lly Co-authored-by: Camila Macedo <7708031+camilamacedo86@users.noreply.github.com> Co-authored-by: Diamon Wiggins <38189728+diamonwiggins@users.noreply.github.com> Co-authored-by: Evans Mungai Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Tom Wieczorek Co-authored-by: Nick Meyer Co-authored-by: Ethan Mosbaugh Co-authored-by: Nathan Sullivan Co-authored-by: ada mancini Co-authored-by: Xav Paice --- config/crds/troubleshoot.sh_analyzers.yaml | 52 ++++++ config/crds/troubleshoot.sh_collectors.yaml | 36 ++++ config/crds/troubleshoot.sh_preflights.yaml | 88 +++++++++ .../crds/troubleshoot.sh_supportbundles.yaml | 88 +++++++++ examples/preflight/mssql.yaml | 70 +++++++ go.mod | 5 +- go.sum | 40 ++++ pkg/analyze/mssql.go | 172 ++++++++++++++++++ pkg/analyze/mssql_test.go | 117 ++++++++++++ .../troubleshoot/v1beta2/analyzer_shared.go | 1 + .../troubleshoot/v1beta2/collector_shared.go | 5 + .../v1beta2/zz_generated.deepcopy.go | 10 + pkg/collect/collector.go | 5 + pkg/collect/mssql.go | 86 +++++++++ pkg/collect/mssql_test.go | 64 +++++++ schemas/analyzer-troubleshoot-v1beta2.json | 80 ++++++++ schemas/collector-troubleshoot-v1beta2.json | 55 ++++++ schemas/preflight-troubleshoot-v1beta2.json | 135 ++++++++++++++ .../supportbundle-troubleshoot-v1beta2.json | 135 ++++++++++++++ 19 files changed, 1243 insertions(+), 1 deletion(-) create mode 100644 examples/preflight/mssql.yaml create mode 100644 pkg/analyze/mssql.go create mode 100644 pkg/analyze/mssql_test.go create mode 100644 pkg/collect/mssql.go create mode 100644 pkg/collect/mssql_test.go diff --git a/config/crds/troubleshoot.sh_analyzers.yaml b/config/crds/troubleshoot.sh_analyzers.yaml index d5d78e64..fa5b592c 100644 --- a/config/crds/troubleshoot.sh_analyzers.yaml +++ b/config/crds/troubleshoot.sh_analyzers.yaml @@ -774,6 +774,58 @@ spec: - namespace - outcomes type: object + mssql: + properties: + annotations: + additionalProperties: + type: string + type: object + checkName: + type: string + collectorName: + type: string + exclude: + type: BoolString + fileName: + type: string + outcomes: + items: + properties: + fail: + properties: + message: + type: string + uri: + type: string + when: + type: string + type: object + pass: + properties: + message: + type: string + uri: + type: string + when: + type: string + type: object + warn: + properties: + message: + type: string + uri: + type: string + when: + type: string + type: object + type: object + type: array + strict: + type: BoolString + required: + - collectorName + - outcomes + type: object mysql: properties: annotations: diff --git a/config/crds/troubleshoot.sh_collectors.yaml b/config/crds/troubleshoot.sh_collectors.yaml index 5cf11d2d..56426279 100644 --- a/config/crds/troubleshoot.sh_collectors.yaml +++ b/config/crds/troubleshoot.sh_collectors.yaml @@ -359,6 +359,42 @@ spec: required: - namespace type: object + mssql: + properties: + collectorName: + type: string + exclude: + type: BoolString + parameters: + items: + type: string + type: array + 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 + uri: + type: string + required: + - uri + type: object mysql: properties: collectorName: diff --git a/config/crds/troubleshoot.sh_preflights.yaml b/config/crds/troubleshoot.sh_preflights.yaml index a1b29377..9c4bc949 100644 --- a/config/crds/troubleshoot.sh_preflights.yaml +++ b/config/crds/troubleshoot.sh_preflights.yaml @@ -774,6 +774,58 @@ spec: - namespace - outcomes type: object + mssql: + properties: + annotations: + additionalProperties: + type: string + type: object + checkName: + type: string + collectorName: + type: string + exclude: + type: BoolString + fileName: + type: string + outcomes: + items: + properties: + fail: + properties: + message: + type: string + uri: + type: string + when: + type: string + type: object + pass: + properties: + message: + type: string + uri: + type: string + when: + type: string + type: object + warn: + properties: + message: + type: string + uri: + type: string + when: + type: string + type: object + type: object + type: array + strict: + type: BoolString + required: + - collectorName + - outcomes + type: object mysql: properties: annotations: @@ -1751,6 +1803,42 @@ spec: required: - namespace type: object + mssql: + properties: + collectorName: + type: string + exclude: + type: BoolString + parameters: + items: + type: string + type: array + 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 + uri: + type: string + required: + - uri + type: object mysql: properties: collectorName: diff --git a/config/crds/troubleshoot.sh_supportbundles.yaml b/config/crds/troubleshoot.sh_supportbundles.yaml index ed162334..bcff2cf3 100644 --- a/config/crds/troubleshoot.sh_supportbundles.yaml +++ b/config/crds/troubleshoot.sh_supportbundles.yaml @@ -805,6 +805,58 @@ spec: - namespace - outcomes type: object + mssql: + properties: + annotations: + additionalProperties: + type: string + type: object + checkName: + type: string + collectorName: + type: string + exclude: + type: BoolString + fileName: + type: string + outcomes: + items: + properties: + fail: + properties: + message: + type: string + uri: + type: string + when: + type: string + type: object + pass: + properties: + message: + type: string + uri: + type: string + when: + type: string + type: object + warn: + properties: + message: + type: string + uri: + type: string + when: + type: string + type: object + type: object + type: array + strict: + type: BoolString + required: + - collectorName + - outcomes + type: object mysql: properties: annotations: @@ -1782,6 +1834,42 @@ spec: required: - namespace type: object + mssql: + properties: + collectorName: + type: string + exclude: + type: BoolString + parameters: + items: + type: string + type: array + 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 + uri: + type: string + required: + - uri + type: object mysql: properties: collectorName: diff --git a/examples/preflight/mssql.yaml b/examples/preflight/mssql.yaml new file mode 100644 index 00000000..9aeb6fd8 --- /dev/null +++ b/examples/preflight/mssql.yaml @@ -0,0 +1,70 @@ +apiVersion: troubleshoot.sh/v1beta2 +kind: Preflight +metadata: + name: sample +spec: + collectors: + - mssql: + collectorName: mssql + uri: sqlserver://SA:nac3lle-ch@stise-bOMBay-wag@db.lab.shortrib.net:1433/master + analyzers: + - mssql: + checkName: Must be SQLServer 15.x or later + collectorName: mssql + outcomes: + - fail: + when: "connected == false" + message: Cannot connect to SQLServer + - fail: + when: "version < 15.x" + message: The SQLServer must be at least version 15 + - pass: + message: The SQLServer connection checks out + - mssql: + checkName: Must be SQLServer 14 or earlier + collectorName: mssql + outcomes: + - fail: + when: "connected == false" + message: Cannot connect to SQLServer + - fail: + when: "version > 14.x" + message: The SQLServer must be at most version 14 + - pass: + message: The SQLServer connection checks out + - mssql: + checkName: Must be SQLServer 15.0.2000.1565 + collectorName: mssql + outcomes: + - fail: + when: "connected == false" + message: Cannot connect to SQLServer + - fail: + when: "version == 15.0.2000.1565" + message: The SQLServer must be version 15.0.2000.1565 + - pass: + message: The SQLServer connection checks out + - mssql: + checkName: Must not be SQLServer 15.0.2000.1565 + collectorName: mssql + outcomes: + - fail: + when: "connected == false" + message: Cannot connect to SQLServer + - fail: + when: "version != 15.0.2000.1565" + message: The SQLServer must not be version 15.0.2000.1565 + - pass: + message: The SQLServer connection checks out + - mssql: + checkName: I don't want to connect to your SQL Server + collectorName: mssql + outcomes: + - fail: + when: "connected == true" + message: Can connect to your SQL Server + - fail: + when: "version != 15.0.2000.1565" + message: The SQLServer must be version 15.0.2000.1565 + - pass: + message: The SQLServer connection checks out diff --git a/go.mod b/go.mod index 20eafb4d..458ba847 100644 --- a/go.mod +++ b/go.mod @@ -24,6 +24,7 @@ require ( github.com/manifoldco/promptui v0.9.0 github.com/mattn/go-isatty v0.0.17 github.com/mholt/archiver/v3 v3.5.1 + github.com/microsoft/go-mssqldb v0.18.0 github.com/opencontainers/image-spec v1.1.0-rc2 github.com/pkg/errors v0.9.1 github.com/replicatedhq/termui/v3 v3.1.1-0.20200811145416-f40076d26851 @@ -57,6 +58,8 @@ require ( github.com/emicklei/go-restful/v3 v3.9.0 // indirect github.com/evanphx/json-patch/v5 v5.6.0 // indirect github.com/go-logr/stdr v1.2.2 // indirect + github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe // indirect + github.com/golang-sql/sqlexp v0.1.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.2.1 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect @@ -126,7 +129,7 @@ require ( github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-safetemp v1.0.0 // indirect - github.com/hashicorp/go-version v1.6.0 // indirect + github.com/hashicorp/go-version v1.6.0 github.com/hashicorp/hcl v1.0.0 // indirect github.com/imdario/mergo v0.3.13 // indirect github.com/inconshreveable/mousetrap v1.0.1 // indirect diff --git a/go.sum b/go.sum index 6fea9354..9b723f43 100644 --- a/go.sum +++ b/go.sum @@ -191,6 +191,10 @@ cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoIS dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/14rcole/gopopulate v0.0.0-20180821133914-b175b219e774 h1:SCbEWT58NSt7d2mcFdvxC9uyrdcTfvBbPLThhkDmXzg= github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.0.0/go.mod h1:uGG2W01BaETf0Ozp+QxxKJdMBNRWPdstHG0Fmdwn1/U= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.1.2/go.mod h1:uGG2W01BaETf0Ozp+QxxKJdMBNRWPdstHG0Fmdwn1/U= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.1.0/go.mod h1:bhXu1AjYL+wutSL/kpSq6s7733q2Rb0yuot9Zgfqa/0= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.0.0/go.mod h1:eWRD7oawr1Mu1sLCawqVc0CUiF43ia3qQMxLscsKQ9w= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= @@ -204,6 +208,7 @@ github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935 github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= +github.com/AzureAD/microsoft-authentication-library-for-go v0.5.1/go.mod h1:Vt9sXTKwMyGcOxSmLDMnGPgqsUg7m8pe215qMLrDXw4= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= @@ -457,6 +462,8 @@ github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8 github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2 h1:aBfCb7iqHmDEIp6fBvC/hQUddQfg+3qdYjwzaiP9Hnc= github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2/go.mod h1:WHNsWjnIn2V1LYOrME7e8KxSeKunYHsxEm4am0BUtcI= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= +github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= +github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/cli v20.10.21+incompatible h1:qVkgyYUnOLQ98LtXBrwd/duVqPT2X4SHndOuGsfwyhU= github.com/docker/cli v20.10.21+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= @@ -598,6 +605,13 @@ github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXP github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= +github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A= +github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -724,6 +738,8 @@ github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2z github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= +github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= @@ -749,6 +765,7 @@ github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+l github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo= github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -776,6 +793,12 @@ github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/ github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= github.com/jackc/pgx/v5 v5.3.0 h1:/NQi8KHMpKWHInxXesC8yD4DhkXPrVhmnwYkjp9AmBA= github.com/jackc/pgx/v5 v5.3.0/go.mod h1:t3JDKnCBlYIc0ewLF0Q7B8MXmoIaBOZj/ic7iHozM/8= +github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= +github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= +github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= +github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= +github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc= +github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= @@ -829,6 +852,7 @@ github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= github.com/linuxkit/virtsock v0.0.0-20201010232012-f8cee7dfc7a3/go.mod h1:3r6x7q95whyfWQpmGZTu3gk3v2YkMi05HEzl7Tf7YEo= @@ -871,6 +895,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfr github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY= github.com/mholt/archiver/v3 v3.5.1 h1:rDjOBX9JSF5BvoJGvjqK479aL70qh9DIpZCl+k7Clwo= github.com/mholt/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4= +github.com/microsoft/go-mssqldb v0.18.0 h1:6Pf95ZIt8mjg3Bm374SlH7RFiez1nGy4xKKOiCw/zFE= +github.com/microsoft/go-mssqldb v0.18.0/go.mod h1:ukJCBnnzLzpVF0qYRT+eg1e+eSwjeQ7IvenUv8QPook= github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= @@ -907,8 +933,10 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0= github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= +github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= @@ -992,6 +1020,8 @@ github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI= github.com/pierrec/lz4/v4 v4.1.2 h1:qvY3YFXRQE/XB8MlLzJH7mSzBs74eA2gg52YTk6jUPM= github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4/go.mod h1:N6UoU20jOqggOuDwUaBQpluzLNDqif3kq9z2wpdYEfQ= +github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -1236,10 +1266,13 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220511200225-c6db032c6c88/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1318,6 +1351,7 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= @@ -1330,6 +1364,7 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= @@ -1477,6 +1512,7 @@ golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1491,6 +1527,7 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220224120231-95c6836cb0e7/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1860,6 +1897,8 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= +gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU= +gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= @@ -1878,6 +1917,7 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/pkg/analyze/mssql.go b/pkg/analyze/mssql.go new file mode 100644 index 00000000..71c55d94 --- /dev/null +++ b/pkg/analyze/mssql.go @@ -0,0 +1,172 @@ +package analyzer + +import ( + "encoding/json" + "fmt" + "path" + "strconv" + "strings" + + "github.com/hashicorp/go-version" + "github.com/pkg/errors" + troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" + "github.com/replicatedhq/troubleshoot/pkg/collect" +) + +func compareMssqlConditionalToActual(conditional string, result *collect.DatabaseConnection) (bool, error) { + parts := strings.Split(strings.TrimSpace(conditional), " ") + + if len(parts) != 3 { + return false, errors.New("unable to parse conditional") + } + + switch parts[0] { + case "connected": + expected, err := strconv.ParseBool(parts[2]) + if err != nil { + return false, errors.Wrap(err, "failed to parse bool") + } + + switch parts[1] { + case "=", "==", "===": + return expected == result.IsConnected, nil + case "!=", "!==": + return expected != result.IsConnected, nil + + } + + return false, errors.New("unable to parse postgres connected analyzer") + + case "version": + expected, err := version.NewVersion(strings.Replace(parts[2], "x", "0", -1)) + if err != nil { + return false, errors.Wrap(err, "failed to parse expected version") + } + + operation := parts[1] + switch operation { + case "=", "==", "===": + operation = "=" + case "!=", "!==": + operation = "!=" + } + + actual, err := version.NewVersion(strings.Replace(result.Version, "x", "0", -1)) + if err != nil { + return false, errors.Wrap(err, "failed to parse mssql db actual version") + } + + constraints, err := version.NewConstraint(fmt.Sprintf("%s %s", operation, expected)) + if err != nil { + return false, errors.Wrap(err, "failed to create constraint") + } + return constraints.Check(actual), nil + } + + return false, nil +} + +func analyzeMssql(analyzer *troubleshootv1beta2.DatabaseAnalyze, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { + collectorName := analyzer.CollectorName + if collectorName == "" { + collectorName = "mssql" + } + + fullPath := path.Join("mssql", fmt.Sprintf("%s.json", collectorName)) + + collected, err := getCollectedFileContents(fullPath) + if err != nil { + return nil, errors.Wrapf(err, "failed to read collected file name: %s", fullPath) + } + + databaseConnection := collect.DatabaseConnection{} + if err := json.Unmarshal(collected, &databaseConnection); err != nil { + return nil, errors.Wrap(err, "failed to unmarshal databased connection result") + } + + title := analyzer.CheckName + if title == "" { + title = collectorName + } + + result := &AnalyzeResult{ + Title: title, + IconKey: "kubernetes_sqlserver_analyze", + IconURI: "https://troubleshoot.sh/images/analyzer-icons/sqlserver-analyze.svg", + } + + for _, outcome := range analyzer.Outcomes { + if outcome.Fail != nil { + if outcome.Fail.When == "" { + result.IsFail = true + result.Message = outcome.Fail.Message + result.URI = outcome.Fail.URI + + return result, nil + } + + isMatch, err := compareMssqlConditionalToActual(outcome.Fail.When, &databaseConnection) + if err != nil { + return result, errors.Wrap(err, "failed to compare MS SQL Server database conditional") + } + + if isMatch { + + if databaseConnection.Error != "" { + result.Message = outcome.Fail.Message + " " + databaseConnection.Error + } else { + result.Message = outcome.Fail.Message + } + + result.IsFail = true + result.URI = outcome.Fail.URI + + return result, nil + } + } else if outcome.Warn != nil { + if outcome.Warn.When == "" { + result.IsWarn = true + result.Message = outcome.Warn.Message + result.URI = outcome.Warn.URI + + return result, nil + } + + isMatch, err := compareMssqlConditionalToActual(outcome.Warn.When, &databaseConnection) + if err != nil { + return result, errors.Wrap(err, "failed to compare MS SQL Server database conditional") + } + + if isMatch { + result.IsWarn = true + result.Message = outcome.Warn.Message + result.URI = outcome.Warn.URI + + return result, nil + } + } else if outcome.Pass != nil { + if outcome.Pass.When == "" { + result.IsPass = true + result.Message = outcome.Pass.Message + result.URI = outcome.Pass.URI + + return result, nil + } + + isMatch, err := compareMssqlConditionalToActual(outcome.Pass.When, &databaseConnection) + if err != nil { + return result, errors.Wrap(err, "failed to compare MS SQL Server database conditional") + } + + if isMatch { + result.IsPass = true + result.Message = outcome.Pass.Message + result.URI = outcome.Pass.URI + + return result, nil + } + } + } + + return result, nil +} diff --git a/pkg/analyze/mssql_test.go b/pkg/analyze/mssql_test.go new file mode 100644 index 00000000..eb3b312d --- /dev/null +++ b/pkg/analyze/mssql_test.go @@ -0,0 +1,117 @@ +package analyzer + +import ( + "testing" + + "github.com/replicatedhq/troubleshoot/pkg/collect" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func Test_compareMssqlConditionalToActual(t *testing.T) { + tests := []struct { + name string + conditional string + conn collect.DatabaseConnection + hasError bool + expect bool + }{ + { + name: "Is Connected Succeeded", + conditional: "connected == true", + conn: collect.DatabaseConnection{ + IsConnected: true, + Error: "", + Version: "", + }, + hasError: false, + expect: true, + }, + { + name: "Is Not Connected Succeeded", + conditional: "connected == false", + conn: collect.DatabaseConnection{ + IsConnected: false, + Error: "", + Version: "", + }, + hasError: false, + expect: true, + }, + { + name: "Exact Match Version String Succeeded", + conditional: "version == 15.0.2000.1565", + conn: collect.DatabaseConnection{ + IsConnected: true, + Error: "", + Version: "15.0.2000.1565", + }, + hasError: false, + expect: true, + }, + { + name: "Less Than Version Match Succeeded", + conditional: "version < 15.x", + conn: collect.DatabaseConnection{ + IsConnected: true, + Error: "", + Version: "14.0.2000.0", + }, + hasError: false, + expect: true, + }, + { + name: "Inverse Less Than Version Match With Greater Than Version Succeeded", + conditional: "version > 15.x", + conn: collect.DatabaseConnection{ + IsConnected: true, + Error: "", + Version: "14.0.2000.0", + }, + hasError: false, + expect: false, + }, + { + name: "Incorrect Conditional Provided Errors", + conditional: "", + conn: collect.DatabaseConnection{}, + hasError: true, + expect: false, + }, + { + name: "Four Part Version Wildcard Match Less Than Succeed", + conditional: "version < 15.0.2000.x", + conn: collect.DatabaseConnection{ + IsConnected: true, + Error: "", + Version: "15.0.1999.0", + }, + hasError: false, + expect: true, + }, + { + name: "Four Part Version Wildcard Match Greater Than Succeed", + conditional: "version > 15.0.2000.x", + conn: collect.DatabaseConnection{ + IsConnected: true, + Error: "", + Version: "15.0.2001.0", + }, + hasError: false, + expect: true, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + req := require.New(t) + actual, err := compareMssqlConditionalToActual(test.conditional, &test.conn) + if test.hasError { + req.Error(err) + } else { + req.NoError(err) + } + assert.Equal(t, test.expect, actual) + + }) + } +} diff --git a/pkg/apis/troubleshoot/v1beta2/analyzer_shared.go b/pkg/apis/troubleshoot/v1beta2/analyzer_shared.go index c14e6f08..b7e9c79b 100644 --- a/pkg/apis/troubleshoot/v1beta2/analyzer_shared.go +++ b/pkg/apis/troubleshoot/v1beta2/analyzer_shared.go @@ -233,6 +233,7 @@ type Analyze struct { YamlCompare *YamlCompare `json:"yamlCompare,omitempty" yaml:"yamlCompare,omitempty"` JsonCompare *JsonCompare `json:"jsonCompare,omitempty" yaml:"jsonCompare,omitempty"` Postgres *DatabaseAnalyze `json:"postgres,omitempty" yaml:"postgres,omitempty"` + Mssql *DatabaseAnalyze `json:"mssql,omitempty" yaml:"mssql,omitempty"` Mysql *DatabaseAnalyze `json:"mysql,omitempty" yaml:"mysql,omitempty"` Redis *DatabaseAnalyze `json:"redis,omitempty" yaml:"redis,omitempty"` CephStatus *CephStatusAnalyze `json:"cephStatus,omitempty" yaml:"cephStatus,omitempty"` diff --git a/pkg/apis/troubleshoot/v1beta2/collector_shared.go b/pkg/apis/troubleshoot/v1beta2/collector_shared.go index 70e63bd8..77406027 100644 --- a/pkg/apis/troubleshoot/v1beta2/collector_shared.go +++ b/pkg/apis/troubleshoot/v1beta2/collector_shared.go @@ -230,6 +230,7 @@ type Collect struct { CopyFromHost *CopyFromHost `json:"copyFromHost,omitempty" yaml:"copyFromHost,omitempty"` HTTP *HTTP `json:"http,omitempty" yaml:"http,omitempty"` Postgres *Database `json:"postgres,omitempty" yaml:"postgres,omitempty"` + Mssql *Database `json:"mssql,omitempty" yaml:"mssql,omitempty"` Mysql *Database `json:"mysql,omitempty" yaml:"mysql,omitempty"` Redis *Database `json:"redis,omitempty" yaml:"redis,omitempty"` Collectd *Collectd `json:"collectd,omitempty" yaml:"collectd,omitempty"` @@ -505,6 +506,10 @@ func (c *Collect) GetName() string { collector = "postgres" name = c.Postgres.CollectorName } + if c.Mssql != nil { + collector = "mssql" + name = c.Mssql.CollectorName + } if c.Mysql != nil { collector = "mysql" name = c.Mysql.CollectorName diff --git a/pkg/apis/troubleshoot/v1beta2/zz_generated.deepcopy.go b/pkg/apis/troubleshoot/v1beta2/zz_generated.deepcopy.go index fdd2b604..abf8fbe3 100644 --- a/pkg/apis/troubleshoot/v1beta2/zz_generated.deepcopy.go +++ b/pkg/apis/troubleshoot/v1beta2/zz_generated.deepcopy.go @@ -149,6 +149,11 @@ func (in *Analyze) DeepCopyInto(out *Analyze) { *out = new(DatabaseAnalyze) (*in).DeepCopyInto(*out) } + if in.Mssql != nil { + in, out := &in.Mssql, &out.Mssql + *out = new(DatabaseAnalyze) + (*in).DeepCopyInto(*out) + } if in.Mysql != nil { in, out := &in.Mysql, &out.Mysql *out = new(DatabaseAnalyze) @@ -745,6 +750,11 @@ func (in *Collect) DeepCopyInto(out *Collect) { *out = new(Database) (*in).DeepCopyInto(*out) } + if in.Mssql != nil { + in, out := &in.Mssql, &out.Mssql + *out = new(Database) + (*in).DeepCopyInto(*out) + } if in.Mysql != nil { in, out := &in.Mysql, &out.Mysql *out = new(Database) diff --git a/pkg/collect/collector.go b/pkg/collect/collector.go index fa57b09f..72ffde1c 100644 --- a/pkg/collect/collector.go +++ b/pkg/collect/collector.go @@ -85,6 +85,8 @@ func GetCollector(collector *troubleshootv1beta2.Collect, bundlePath string, nam return &CollectHTTP{collector.HTTP, bundlePath, namespace, clientConfig, client, RBACErrors}, true case collector.Postgres != nil: return &CollectPostgres{collector.Postgres, bundlePath, namespace, clientConfig, client, ctx, RBACErrors}, true + case collector.Mssql != nil: + return &CollectMssql{collector.Mssql, bundlePath, namespace, clientConfig, client, ctx, RBACErrors}, true case collector.Mysql != nil: return &CollectMysql{collector.Mysql, bundlePath, namespace, clientConfig, client, ctx, RBACErrors}, true case collector.Redis != nil: @@ -150,6 +152,9 @@ func getCollectorName(c interface{}) string { case *CollectPostgres: collector = "postgres" name = v.Collector.CollectorName + case *CollectMssql: + collector = "mssql" + name = v.Collector.CollectorName case *CollectMysql: collector = "mysql" name = v.Collector.CollectorName diff --git a/pkg/collect/mssql.go b/pkg/collect/mssql.go new file mode 100644 index 00000000..47b71f07 --- /dev/null +++ b/pkg/collect/mssql.go @@ -0,0 +1,86 @@ +package collect + +import ( + "bytes" + "context" + "database/sql" + "encoding/json" + "fmt" + "regexp" + + _ "github.com/microsoft/go-mssqldb" + "github.com/pkg/errors" + troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" +) + +type CollectMssql struct { + Collector *troubleshootv1beta2.Database + BundlePath string + Namespace string + ClientConfig *rest.Config + Client kubernetes.Interface + Context context.Context + RBACErrors +} + +func (c *CollectMssql) Title() string { + return getCollectorName(c) +} + +func (c *CollectMssql) IsExcluded() (bool, error) { + return isExcluded(c.Collector.Exclude) +} + +func (c *CollectMssql) Collect(progressChan chan<- interface{}) (CollectorResult, error) { + databaseConnection := DatabaseConnection{} + + db, err := sql.Open("mssql", c.Collector.URI) + if err != nil { + databaseConnection.Error = err.Error() + } else { + query := `select @@VERSION as version` + row := db.QueryRow(query) + version := "" + if err := row.Scan(&version); err != nil { + databaseConnection.Error = err.Error() + } else { + databaseConnection.IsConnected = true + + mssqlVersion, err := parseMsSqlVersion(version) + if err != nil { + databaseConnection.Version = "Unknown" + databaseConnection.Error = err.Error() + } else { + databaseConnection.Version = mssqlVersion + } + } + } + + b, err := json.Marshal(databaseConnection) + if err != nil { + return nil, errors.Wrap(err, "failed to marshal database connection") + } + + collectorName := c.Collector.CollectorName + if collectorName == "" { + collectorName = "mssql" + } + + output := NewResult() + output.SaveResult(c.BundlePath, fmt.Sprintf("mssql/%s.json", collectorName), bytes.NewBuffer(b)) + + return output, nil +} + +func parseMsSqlVersion(mssqlVersion string) (string, error) { + re := regexp.MustCompile(".*SQL.*-\\s+([0-9.]+)") + matches := re.FindStringSubmatch(mssqlVersion) + if len(matches) < 2 { + return "", errors.Errorf("mssql version did not match regex: %q", mssqlVersion) + } + + return matches[1], nil + +} diff --git a/pkg/collect/mssql_test.go b/pkg/collect/mssql_test.go new file mode 100644 index 00000000..1b145165 --- /dev/null +++ b/pkg/collect/mssql_test.go @@ -0,0 +1,64 @@ +package collect + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func Test_parseMsSqlVersion(t *testing.T) { + tests := []struct { + name string + mssqlVersion string + expect string + hasError bool + }{ + { + name: "Valid String Succeed", + mssqlVersion: `Microsoft Azure SQL Edge Developer (RTM) - 15.0.2000.1565 (ARM64) + Jun 14 2022 00:37:12 + Copyright (C) 2019 Microsoft Corporation + Linux (Ubuntu 18.04.6 LTS aarch64) `, + expect: "15.0.2000.1565", + hasError: false, + }, + { + name: "SemVer String Pass", + mssqlVersion: `Microsoft Azure SQL Edge Developer (RTM) - 15.0.1565 (ARM64) + Jun 14 2022 00:37:12 + Copyright (C) 2019 Microsoft Corporation + Linux (Ubuntu 18.04.6 LTS aarch64) `, + expect: "15.0.1565", + hasError: false, + }, + { + name: "Missing SQL Fail", + mssqlVersion: `Microsoft Azure Edge Developer (RTM) - 15.1.2020.1565 (ARM64) + Jun 14 2022 00:37:12 + Copyright (C) 2019 Microsoft Corporation + Linux (Ubuntu 18.04.6 LTS aarch64) `, + expect: "", + hasError: true, + }, + { + name: "Empty String Fail", + mssqlVersion: "", + expect: "", + hasError: true, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + req := require.New(t) + actual, err := parseMsSqlVersion(test.mssqlVersion) + if test.hasError { + req.Error(err) + } else { + req.NoError(err) + } + assert.Equal(t, test.expect, actual) + + }) + } +} diff --git a/schemas/analyzer-troubleshoot-v1beta2.json b/schemas/analyzer-troubleshoot-v1beta2.json index bde7047e..9cfc5368 100644 --- a/schemas/analyzer-troubleshoot-v1beta2.json +++ b/schemas/analyzer-troubleshoot-v1beta2.json @@ -1154,6 +1154,86 @@ } } }, + "mssql": { + "type": "object", + "required": [ + "collectorName", + "outcomes" + ], + "properties": { + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "checkName": { + "type": "string" + }, + "collectorName": { + "type": "string" + }, + "exclude": { + "oneOf": [{"type": "string"},{"type": "boolean"}] + }, + "fileName": { + "type": "string" + }, + "outcomes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "fail": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "uri": { + "type": "string" + }, + "when": { + "type": "string" + } + } + }, + "pass": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "uri": { + "type": "string" + }, + "when": { + "type": "string" + } + } + }, + "warn": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "uri": { + "type": "string" + }, + "when": { + "type": "string" + } + } + } + } + } + }, + "strict": { + "oneOf": [{"type": "string"},{"type": "boolean"}] + } + } + }, "mysql": { "type": "object", "required": [ diff --git a/schemas/collector-troubleshoot-v1beta2.json b/schemas/collector-troubleshoot-v1beta2.json index c4121567..e0c8b7fb 100644 --- a/schemas/collector-troubleshoot-v1beta2.json +++ b/schemas/collector-troubleshoot-v1beta2.json @@ -507,6 +507,61 @@ } } }, + "mssql": { + "type": "object", + "required": [ + "uri" + ], + "properties": { + "collectorName": { + "type": "string" + }, + "exclude": { + "oneOf": [{"type": "string"},{"type": "boolean"}] + }, + "parameters": { + "type": "array", + "items": { + "type": "string" + } + }, + "tls": { + "type": "object", + "properties": { + "cacert": { + "type": "string" + }, + "clientCert": { + "type": "string" + }, + "clientKey": { + "type": "string" + }, + "secret": { + "type": "object", + "required": [ + "name", + "namespace" + ], + "properties": { + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + } + } + }, + "skipVerify": { + "type": "boolean" + } + } + }, + "uri": { + "type": "string" + } + } + }, "mysql": { "type": "object", "required": [ diff --git a/schemas/preflight-troubleshoot-v1beta2.json b/schemas/preflight-troubleshoot-v1beta2.json index 644e6995..8a9f3ffa 100644 --- a/schemas/preflight-troubleshoot-v1beta2.json +++ b/schemas/preflight-troubleshoot-v1beta2.json @@ -1154,6 +1154,86 @@ } } }, + "mssql": { + "type": "object", + "required": [ + "collectorName", + "outcomes" + ], + "properties": { + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "checkName": { + "type": "string" + }, + "collectorName": { + "type": "string" + }, + "exclude": { + "oneOf": [{"type": "string"},{"type": "boolean"}] + }, + "fileName": { + "type": "string" + }, + "outcomes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "fail": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "uri": { + "type": "string" + }, + "when": { + "type": "string" + } + } + }, + "pass": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "uri": { + "type": "string" + }, + "when": { + "type": "string" + } + } + }, + "warn": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "uri": { + "type": "string" + }, + "when": { + "type": "string" + } + } + } + } + } + }, + "strict": { + "oneOf": [{"type": "string"},{"type": "boolean"}] + } + } + }, "mysql": { "type": "object", "required": [ @@ -2651,6 +2731,61 @@ } } }, + "mssql": { + "type": "object", + "required": [ + "uri" + ], + "properties": { + "collectorName": { + "type": "string" + }, + "exclude": { + "oneOf": [{"type": "string"},{"type": "boolean"}] + }, + "parameters": { + "type": "array", + "items": { + "type": "string" + } + }, + "tls": { + "type": "object", + "properties": { + "cacert": { + "type": "string" + }, + "clientCert": { + "type": "string" + }, + "clientKey": { + "type": "string" + }, + "secret": { + "type": "object", + "required": [ + "name", + "namespace" + ], + "properties": { + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + } + } + }, + "skipVerify": { + "type": "boolean" + } + } + }, + "uri": { + "type": "string" + } + } + }, "mysql": { "type": "object", "required": [ diff --git a/schemas/supportbundle-troubleshoot-v1beta2.json b/schemas/supportbundle-troubleshoot-v1beta2.json index 43e02b29..63c4f147 100644 --- a/schemas/supportbundle-troubleshoot-v1beta2.json +++ b/schemas/supportbundle-troubleshoot-v1beta2.json @@ -1200,6 +1200,86 @@ } } }, + "mssql": { + "type": "object", + "required": [ + "collectorName", + "outcomes" + ], + "properties": { + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "checkName": { + "type": "string" + }, + "collectorName": { + "type": "string" + }, + "exclude": { + "oneOf": [{"type": "string"},{"type": "boolean"}] + }, + "fileName": { + "type": "string" + }, + "outcomes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "fail": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "uri": { + "type": "string" + }, + "when": { + "type": "string" + } + } + }, + "pass": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "uri": { + "type": "string" + }, + "when": { + "type": "string" + } + } + }, + "warn": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "uri": { + "type": "string" + }, + "when": { + "type": "string" + } + } + } + } + } + }, + "strict": { + "oneOf": [{"type": "string"},{"type": "boolean"}] + } + } + }, "mysql": { "type": "object", "required": [ @@ -2697,6 +2777,61 @@ } } }, + "mssql": { + "type": "object", + "required": [ + "uri" + ], + "properties": { + "collectorName": { + "type": "string" + }, + "exclude": { + "oneOf": [{"type": "string"},{"type": "boolean"}] + }, + "parameters": { + "type": "array", + "items": { + "type": "string" + } + }, + "tls": { + "type": "object", + "properties": { + "cacert": { + "type": "string" + }, + "clientCert": { + "type": "string" + }, + "clientKey": { + "type": "string" + }, + "secret": { + "type": "object", + "required": [ + "name", + "namespace" + ], + "properties": { + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + } + } + }, + "skipVerify": { + "type": "boolean" + } + } + }, + "uri": { + "type": "string" + } + } + }, "mysql": { "type": "object", "required": [