From df0a62306f0b73edc4ec402dbcfb9879bf45dd8e Mon Sep 17 00:00:00 2001 From: Chuck D'Antonio Date: Mon, 30 Jan 2023 14:39:46 -0500 Subject: [PATCH 01/55] Adds MSSQL collector based on Postgres collector --- go.mod | 3 ++ go.sum | 46 ++++++++++++++++++++++++ pkg/collect/mssql.go | 86 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 135 insertions(+) create mode 100644 pkg/collect/mssql.go diff --git a/go.mod b/go.mod index ebba8e824..9696f7adf 100644 --- a/go.mod +++ b/go.mod @@ -53,10 +53,13 @@ require ( github.com/docker/distribution v2.8.1+incompatible // indirect github.com/emicklei/go-restful/v3 v3.9.0 // indirect github.com/evanphx/json-patch/v5 v5.6.0 // 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.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect + github.com/microsoft/go-mssqldb v0.18.0 // indirect github.com/mistifyio/go-zfs/v3 v3.0.0 // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect diff --git a/go.sum b/go.sum index 4f20df97a..980e1a64b 100644 --- a/go.sum +++ b/go.sum @@ -50,6 +50,10 @@ cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi 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= @@ -63,6 +67,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= @@ -310,6 +315,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= @@ -445,6 +452,15 @@ 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.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= +github.com/golang-jwt/jwt/v4 v4.2.0 h1:besgBTC8w8HjP6NzQdxwKH9Z5oQMZ24ThTrHp3cZ8eU= +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= @@ -549,6 +565,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= @@ -574,6 +592,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.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.3.0 h1:McDWVJIU/y+u1BRV06dPaLfLCaT7fUTJLp5r04x7iNw= github.com/hashicorp/go-version v1.3.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= @@ -602,6 +621,12 @@ github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHF github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= github.com/jackc/pgx/v5 v5.2.0 h1:NdPpngX0Y6z6XDFKqmFQaE+bCtkqzvQIOt1wvBlAqs8= github.com/jackc/pgx/v5 v5.2.0/go.mod h1:Ptn7zmohNsWEsdxRawMzk3gaKma2obW+NWTnKa0S4nk= +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= @@ -655,6 +680,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= @@ -697,6 +723,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= @@ -734,8 +762,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= @@ -821,6 +851,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= @@ -1055,11 +1087,17 @@ 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-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= +golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +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.0.0-20220919173607-35f4265a4bc0 h1:a5Yg6ylndHHYJqIPrdq0AhvR6KTvDTAvgBtaidhEevY= +golang.org/x/crypto v0.0.0-20220919173607-35f4265a4bc0/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1134,6 +1172,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= @@ -1257,12 +1296,17 @@ golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/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-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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-20220517195934-5e4e11fc645e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1498,6 +1542,7 @@ 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/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= @@ -1516,6 +1561,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/collect/mssql.go b/pkg/collect/mssql.go new file mode 100644 index 000000000..cdcc7ca2c --- /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 + ctx context.Context + RBACErrors +} + +func (c *CollectMSSql) Title() string { + return collectorTitleOrDefault(c.Collector.CollectorMeta, "MSSSQLServer") +} + +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("MSSQLServer ([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 + +} From a38f223d42c9810ba96a9f1a7a6ad8857e3d1bc9 Mon Sep 17 00:00:00 2001 From: Chuck D'Antonio Date: Tue, 20 Dec 2022 15:43:38 -0500 Subject: [PATCH 02/55] Adds tests for MSSQL based on the tests for Postgres --- pkg/collect/mssql_test.go | 81 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 pkg/collect/mssql_test.go diff --git a/pkg/collect/mssql_test.go b/pkg/collect/mssql_test.go new file mode 100644 index 000000000..016ee0fa7 --- /dev/null +++ b/pkg/collect/mssql_test.go @@ -0,0 +1,81 @@ +package collect + +import ( + "context" + "testing" + + "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + testclient "k8s.io/client-go/kubernetes/fake" +) + +func Test_parseMSSqlVersion(t *testing.T) { + tests := []struct { + mssqlVersion string + expect string + }{ + { + // docker run -d --name pgnine -e POSTGRES_PASSWORD=password mssql:9 + 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", + }, + } + for _, test := range tests { + t.Run(test.mssqlVersion, func(t *testing.T) { + req := require.New(t) + actual, err := parseMSSqlVersion(test.mssqlVersion) + req.NoError(err) + + assert.Equal(t, test.expect, actual) + + }) + } +} + +func TestCollectMSSql_createConnectConfigPlainText(t *testing.T) { + tests := []struct { + name string + uri string + hasError bool + }{ + { + name: "valid uri creates mssql connection config successfully", + uri: "sqlserver://user:password@sql.contoso.com:1433/master", + }, + { + name: "empty uri fails to create mssql connection config with error", + uri: "", + hasError: true, + }, + { + name: "invalid protocol fails to create mssql connection config with error", + uri: "http://somehost:5432", + hasError: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := &CollectMSSql{ + Context: context.Background(), + Collector: &v1beta2.Database{ + URI: tt.uri, + }, + } + + connCfg, err := c.createConnectConfig() + assert.Equal(t, err != nil, tt.hasError) + if err == nil { + require.NotNil(t, connCfg) + assert.Equal(t, connCfg.Host, "sql.contoso.com") + assert.Equal(t, connCfg.Database, "master") + } else { + t.Log(err) + assert.Nil(t, connCfg) + } + }) + } +} From 65fba5876a5bd0c25cd0318ed4afbb56d0dc370b Mon Sep 17 00:00:00 2001 From: Chuck D'Antonio Date: Wed, 21 Dec 2022 13:17:39 -0500 Subject: [PATCH 03/55] Adds analyzer --- pkg/analyze/mssql.go | 116 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 pkg/analyze/mssql.go diff --git a/pkg/analyze/mssql.go b/pkg/analyze/mssql.go new file mode 100644 index 000000000..44bd32c0c --- /dev/null +++ b/pkg/analyze/mssql.go @@ -0,0 +1,116 @@ +package analyzer + +import ( + "encoding/json" + "fmt" + "path" + + "github.com/pkg/errors" + troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" + "github.com/replicatedhq/troubleshoot/pkg/collect" +) + +func analyzeMsSQLServer(analyzer *troubleshootv1beta2.DatabaseAnalyze, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { + collectorName := analyzer.CollectorName + if collectorName == "" { + collectorName = "MsSqlServer" + } + + 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_MS SQL Server_analyze", + IconURI: "https://troubleshoot.sh/images/analyzer-icons/MS SQL Server-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 := compareDatabaseConditionalToActual(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 := compareDatabaseConditionalToActual(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 := compareDatabaseConditionalToActual(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 +} From 3cb41f3c35dbaef493069ce9b4e5cbe3507d7836 Mon Sep 17 00:00:00 2001 From: Chuck D'Antonio Date: Wed, 21 Dec 2022 13:18:00 -0500 Subject: [PATCH 04/55] Adds MS SQL Server example --- examples/preflight/mssql.yaml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 examples/preflight/mssql.yaml diff --git a/examples/preflight/mssql.yaml b/examples/preflight/mssql.yaml new file mode 100644 index 000000000..04de88298 --- /dev/null +++ b/examples/preflight/mssql.yaml @@ -0,0 +1,22 @@ +apiVersion: troubleshoot.sh/v1beta2 +kind: Preflight +metadata: + name: sample +spec: + collectors: + - postgres: + collectorName: mssql + uri: sqlserver://user:password@hostname:1433/master + analyzers: + - postgres: + checkName: Must be SQLServer 15.x or later + collectorName: mssql + outcomes: + - fail: + when: "connected == false" + message: Cannot connect to postgres server + - fail: + when: "version < 15.x" + message: The postgres server must be at least version 15 + - pass: + message: The postgres connection checks out From ae93c9a3862b7630694a77397bc608f27c5bedb1 Mon Sep 17 00:00:00 2001 From: Chuck D'Antonio Date: Wed, 21 Dec 2022 13:18:40 -0500 Subject: [PATCH 05/55] Assures MS SQL tests pass --- pkg/collect/mssql.go | 16 +++++------ pkg/collect/mssql_test.go | 58 ++++----------------------------------- 2 files changed, 13 insertions(+), 61 deletions(-) diff --git a/pkg/collect/mssql.go b/pkg/collect/mssql.go index cdcc7ca2c..ff691078d 100644 --- a/pkg/collect/mssql.go +++ b/pkg/collect/mssql.go @@ -15,25 +15,25 @@ import ( "k8s.io/client-go/rest" ) -type CollectMSSql struct { +type CollectMsSql struct { Collector *troubleshootv1beta2.Database BundlePath string Namespace string ClientConfig *rest.Config Client kubernetes.Interface - ctx context.Context + Context context.Context RBACErrors } -func (c *CollectMSSql) Title() string { +func (c *CollectMsSql) Title() string { return collectorTitleOrDefault(c.Collector.CollectorMeta, "MSSSQLServer") } -func (c *CollectMSSql) IsExcluded() (bool, error) { +func (c *CollectMsSql) IsExcluded() (bool, error) { return isExcluded(c.Collector.Exclude) } -func (c *CollectMSSql) Collect(progressChan chan<- interface{}) (CollectorResult, error) { +func (c *CollectMsSql) Collect(progressChan chan<- interface{}) (CollectorResult, error) { databaseConnection := DatabaseConnection{} db, err := sql.Open("mssql", c.Collector.URI) @@ -48,7 +48,7 @@ func (c *CollectMSSql) Collect(progressChan chan<- interface{}) (CollectorResult } else { databaseConnection.IsConnected = true - mssqlVersion, err := parseMSSqlVersion(version) + mssqlVersion, err := parseMsSqlVersion(version) if err != nil { databaseConnection.Version = "Unknown" databaseConnection.Error = err.Error() @@ -74,8 +74,8 @@ func (c *CollectMSSql) Collect(progressChan chan<- interface{}) (CollectorResult return output, nil } -func parseMSSqlVersion(mssqlVersion string) (string, error) { - re := regexp.MustCompile("MSSQLServer ([0-9.]*)") +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) diff --git a/pkg/collect/mssql_test.go b/pkg/collect/mssql_test.go index 016ee0fa7..ffd8f359f 100644 --- a/pkg/collect/mssql_test.go +++ b/pkg/collect/mssql_test.go @@ -1,33 +1,29 @@ package collect import ( - "context" "testing" - "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - testclient "k8s.io/client-go/kubernetes/fake" ) -func Test_parseMSSqlVersion(t *testing.T) { +func Test_parseMsSqlVersion(t *testing.T) { tests := []struct { mssqlVersion string expect string }{ { - // docker run -d --name pgnine -e POSTGRES_PASSWORD=password mssql:9 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) `, +Jun 14 2022 00:37:12 +Copyright (C) 2019 Microsoft Corporation +Linux (Ubuntu 18.04.6 LTS aarch64) `, expect: "15.0.2000.1565", }, } for _, test := range tests { t.Run(test.mssqlVersion, func(t *testing.T) { req := require.New(t) - actual, err := parseMSSqlVersion(test.mssqlVersion) + actual, err := parseMsSqlVersion(test.mssqlVersion) req.NoError(err) assert.Equal(t, test.expect, actual) @@ -35,47 +31,3 @@ func Test_parseMSSqlVersion(t *testing.T) { }) } } - -func TestCollectMSSql_createConnectConfigPlainText(t *testing.T) { - tests := []struct { - name string - uri string - hasError bool - }{ - { - name: "valid uri creates mssql connection config successfully", - uri: "sqlserver://user:password@sql.contoso.com:1433/master", - }, - { - name: "empty uri fails to create mssql connection config with error", - uri: "", - hasError: true, - }, - { - name: "invalid protocol fails to create mssql connection config with error", - uri: "http://somehost:5432", - hasError: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - c := &CollectMSSql{ - Context: context.Background(), - Collector: &v1beta2.Database{ - URI: tt.uri, - }, - } - - connCfg, err := c.createConnectConfig() - assert.Equal(t, err != nil, tt.hasError) - if err == nil { - require.NotNil(t, connCfg) - assert.Equal(t, connCfg.Host, "sql.contoso.com") - assert.Equal(t, connCfg.Database, "master") - } else { - t.Log(err) - assert.Nil(t, connCfg) - } - }) - } -} From 01836909a08d0e76dc39600d5423fcb7b455ebdd Mon Sep 17 00:00:00 2001 From: Chuck D'Antonio Date: Tue, 3 Jan 2023 17:04:55 -0500 Subject: [PATCH 06/55] Aligns naming and adds to API --- examples/preflight/mssql.yaml | 8 ++++---- pkg/analyze/mssql.go | 8 ++++---- pkg/apis/troubleshoot/v1beta2/analyzer_shared.go | 1 + pkg/apis/troubleshoot/v1beta2/collector_shared.go | 5 +++++ pkg/apis/troubleshoot/v1beta2/zz_generated.deepcopy.go | 10 ++++++++++ pkg/collect/mssql.go | 2 +- 6 files changed, 25 insertions(+), 9 deletions(-) diff --git a/examples/preflight/mssql.yaml b/examples/preflight/mssql.yaml index 04de88298..87cf067df 100644 --- a/examples/preflight/mssql.yaml +++ b/examples/preflight/mssql.yaml @@ -4,11 +4,11 @@ metadata: name: sample spec: collectors: - - postgres: + - mssql: collectorName: mssql uri: sqlserver://user:password@hostname:1433/master analyzers: - - postgres: + - mssql: checkName: Must be SQLServer 15.x or later collectorName: mssql outcomes: @@ -17,6 +17,6 @@ spec: message: Cannot connect to postgres server - fail: when: "version < 15.x" - message: The postgres server must be at least version 15 + message: The SQLServer must be at least version 15 - pass: - message: The postgres connection checks out + message: The SQLServer connection checks out diff --git a/pkg/analyze/mssql.go b/pkg/analyze/mssql.go index 44bd32c0c..699a64001 100644 --- a/pkg/analyze/mssql.go +++ b/pkg/analyze/mssql.go @@ -10,10 +10,10 @@ import ( "github.com/replicatedhq/troubleshoot/pkg/collect" ) -func analyzeMsSQLServer(analyzer *troubleshootv1beta2.DatabaseAnalyze, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { +func analyzeMsssql(analyzer *troubleshootv1beta2.DatabaseAnalyze, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { collectorName := analyzer.CollectorName if collectorName == "" { - collectorName = "MsSqlServer" + collectorName = "mssql" } fullPath := path.Join("mssql", fmt.Sprintf("%s.json", collectorName)) @@ -35,8 +35,8 @@ func analyzeMsSQLServer(analyzer *troubleshootv1beta2.DatabaseAnalyze, getCollec result := &AnalyzeResult{ Title: title, - IconKey: "kubernetes_MS SQL Server_analyze", - IconURI: "https://troubleshoot.sh/images/analyzer-icons/MS SQL Server-analyze.svg", + IconKey: "kubernetes_sqlserver_analyze", + IconURI: "https://troubleshoot.sh/images/analyzer-icons/sqlserver-analyze.svg", } for _, outcome := range analyzer.Outcomes { diff --git a/pkg/apis/troubleshoot/v1beta2/analyzer_shared.go b/pkg/apis/troubleshoot/v1beta2/analyzer_shared.go index c14e6f087..b7e9c79b0 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 70e63bd82..77406027e 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 29b154d1d..87a87e3dd 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/mssql.go b/pkg/collect/mssql.go index ff691078d..20ecaff81 100644 --- a/pkg/collect/mssql.go +++ b/pkg/collect/mssql.go @@ -15,7 +15,7 @@ import ( "k8s.io/client-go/rest" ) -type CollectMsSql struct { +type CollectMssql struct { Collector *troubleshootv1beta2.Database BundlePath string Namespace string From e5be946f9ba0f858cd2b54bab25ab0f06ca75d4c Mon Sep 17 00:00:00 2001 From: Chuck D'Antonio Date: Tue, 3 Jan 2023 17:08:17 -0500 Subject: [PATCH 07/55] Corrects names that weren't updated --- pkg/collect/mssql.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/collect/mssql.go b/pkg/collect/mssql.go index 20ecaff81..d19387515 100644 --- a/pkg/collect/mssql.go +++ b/pkg/collect/mssql.go @@ -25,15 +25,15 @@ type CollectMssql struct { RBACErrors } -func (c *CollectMsSql) Title() string { +func (c *CollectMssql) Title() string { return collectorTitleOrDefault(c.Collector.CollectorMeta, "MSSSQLServer") } -func (c *CollectMsSql) IsExcluded() (bool, error) { +func (c *CollectMssql) IsExcluded() (bool, error) { return isExcluded(c.Collector.Exclude) } -func (c *CollectMsSql) Collect(progressChan chan<- interface{}) (CollectorResult, error) { +func (c *CollectMssql) Collect(progressChan chan<- interface{}) (CollectorResult, error) { databaseConnection := DatabaseConnection{} db, err := sql.Open("mssql", c.Collector.URI) From ffd1d1125ea829f6a136ac0a47e4a6a103b28960 Mon Sep 17 00:00:00 2001 From: Chuck D'Antonio Date: Wed, 4 Jan 2023 09:43:19 -0500 Subject: [PATCH 08/55] Updates text on sample --- examples/preflight/mssql.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/preflight/mssql.yaml b/examples/preflight/mssql.yaml index 87cf067df..a25f0b6bd 100644 --- a/examples/preflight/mssql.yaml +++ b/examples/preflight/mssql.yaml @@ -6,7 +6,7 @@ spec: collectors: - mssql: collectorName: mssql - uri: sqlserver://user:password@hostname:1433/master + uri: sqlserver://SA:P%40w0rd1@technonook.com:1433/master analyzers: - mssql: checkName: Must be SQLServer 15.x or later @@ -14,7 +14,7 @@ spec: outcomes: - fail: when: "connected == false" - message: Cannot connect to postgres server + message: Cannot connect to SQLServer - fail: when: "version < 15.x" message: The SQLServer must be at least version 15 From 70ded478ac2f9219fd160e91afa59a58a6185b93 Mon Sep 17 00:00:00 2001 From: Chuck D'Antonio Date: Wed, 4 Jan 2023 09:44:02 -0500 Subject: [PATCH 09/55] Corrects typo --- pkg/analyze/mssql.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/analyze/mssql.go b/pkg/analyze/mssql.go index 699a64001..da1f0b4aa 100644 --- a/pkg/analyze/mssql.go +++ b/pkg/analyze/mssql.go @@ -10,7 +10,7 @@ import ( "github.com/replicatedhq/troubleshoot/pkg/collect" ) -func analyzeMsssql(analyzer *troubleshootv1beta2.DatabaseAnalyze, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { +func analyzeMssql(analyzer *troubleshootv1beta2.DatabaseAnalyze, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { collectorName := analyzer.CollectorName if collectorName == "" { collectorName = "mssql" From 0d33634420d1ff69334b56872f5db969c65dbc3e Mon Sep 17 00:00:00 2001 From: Chuck D'Antonio Date: Wed, 4 Jan 2023 09:44:27 -0500 Subject: [PATCH 10/55] Makes troubleshoot aware of mssql --- pkg/analyze/analyzer.go | 15 +++++++++++++++ pkg/collect/collector.go | 5 +++++ 2 files changed, 20 insertions(+) diff --git a/pkg/analyze/analyzer.go b/pkg/analyze/analyzer.go index cb6e470a8..96730dabf 100644 --- a/pkg/analyze/analyzer.go +++ b/pkg/analyze/analyzer.go @@ -399,6 +399,21 @@ func Analyze(analyzer *troubleshootv1beta2.Analyze, getFile getCollectedFileCont result.Strict = analyzer.Postgres.Strict.BoolOrDefaultFalse() return []*AnalyzeResult{result}, nil } + if analyzer.Mssql != nil { + isExcluded, err := isExcluded(analyzer.Mssql.Exclude) + if err != nil { + return nil, err + } + if isExcluded { + return nil, nil + } + result, err := analyzeMssql(analyzer.Mssql, getFile) + if err != nil { + return nil, err + } + result.Strict = analyzer.Mssql.Strict.BoolOrDefaultFalse() + return []*AnalyzeResult{result}, nil + } if analyzer.Mysql != nil { isExcluded, err := isExcluded(analyzer.Mysql.Exclude) if err != nil { diff --git a/pkg/collect/collector.go b/pkg/collect/collector.go index 50e5d20bf..4104f5705 100644 --- a/pkg/collect/collector.go +++ b/pkg/collect/collector.go @@ -84,6 +84,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: @@ -156,6 +158,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 From 715f28f46429427f39d855e521bafdff5cb46324 Mon Sep 17 00:00:00 2001 From: Chuck D'Antonio Date: Mon, 30 Jan 2023 14:30:03 -0500 Subject: [PATCH 11/55] Uses Hashicorp version library for SQL Server versions --- examples/preflight/mssql.yaml | 50 +++++++++++++++++++++++++++- go.sum | 3 ++ pkg/analyze/mssql.go | 62 +++++++++++++++++++++++++++++++++-- 3 files changed, 111 insertions(+), 4 deletions(-) diff --git a/examples/preflight/mssql.yaml b/examples/preflight/mssql.yaml index a25f0b6bd..9aeb6fd81 100644 --- a/examples/preflight/mssql.yaml +++ b/examples/preflight/mssql.yaml @@ -6,7 +6,7 @@ spec: collectors: - mssql: collectorName: mssql - uri: sqlserver://SA:P%40w0rd1@technonook.com:1433/master + uri: sqlserver://SA:nac3lle-ch@stise-bOMBay-wag@db.lab.shortrib.net:1433/master analyzers: - mssql: checkName: Must be SQLServer 15.x or later @@ -20,3 +20,51 @@ spec: 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.sum b/go.sum index 980e1a64b..029c10082 100644 --- a/go.sum +++ b/go.sum @@ -1098,6 +1098,8 @@ golang.org/x/crypto v0.0.0-20220511200225-c6db032c6c88/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220919173607-35f4265a4bc0 h1:a5Yg6ylndHHYJqIPrdq0AhvR6KTvDTAvgBtaidhEevY= golang.org/x/crypto v0.0.0-20220919173607-35f4265a4bc0/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8= +golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1182,6 +1184,7 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= 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.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw= diff --git a/pkg/analyze/mssql.go b/pkg/analyze/mssql.go index da1f0b4aa..71c55d944 100644 --- a/pkg/analyze/mssql.go +++ b/pkg/analyze/mssql.go @@ -4,12 +4,68 @@ 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 == "" { @@ -49,7 +105,7 @@ func analyzeMssql(analyzer *troubleshootv1beta2.DatabaseAnalyze, getCollectedFil return result, nil } - isMatch, err := compareDatabaseConditionalToActual(outcome.Fail.When, &databaseConnection) + isMatch, err := compareMssqlConditionalToActual(outcome.Fail.When, &databaseConnection) if err != nil { return result, errors.Wrap(err, "failed to compare MS SQL Server database conditional") } @@ -76,7 +132,7 @@ func analyzeMssql(analyzer *troubleshootv1beta2.DatabaseAnalyze, getCollectedFil return result, nil } - isMatch, err := compareDatabaseConditionalToActual(outcome.Warn.When, &databaseConnection) + isMatch, err := compareMssqlConditionalToActual(outcome.Warn.When, &databaseConnection) if err != nil { return result, errors.Wrap(err, "failed to compare MS SQL Server database conditional") } @@ -97,7 +153,7 @@ func analyzeMssql(analyzer *troubleshootv1beta2.DatabaseAnalyze, getCollectedFil return result, nil } - isMatch, err := compareDatabaseConditionalToActual(outcome.Pass.When, &databaseConnection) + isMatch, err := compareMssqlConditionalToActual(outcome.Pass.When, &databaseConnection) if err != nil { return result, errors.Wrap(err, "failed to compare MS SQL Server database conditional") } From dbc7e5d9b4adbb76d122ff5ad378070b99af8297 Mon Sep 17 00:00:00 2001 From: Chuck D'Antonio Date: Mon, 30 Jan 2023 14:43:22 -0500 Subject: [PATCH 12/55] Resyncs generated file --- pkg/client/troubleshootclientset/clientset.go | 44 +++++-------------- .../v1beta1/fake/fake_analyzer.go | 2 +- .../v1beta1/fake/fake_collector.go | 2 +- .../v1beta1/fake/fake_preflight.go | 2 +- .../v1beta1/fake/fake_redactor.go | 2 +- .../v1beta1/fake/fake_supportbundle.go | 2 +- .../v1beta1/troubleshoot_client.go | 20 +-------- .../v1beta2/fake/fake_analyzer.go | 2 +- .../v1beta2/fake/fake_collector.go | 2 +- .../v1beta2/fake/fake_hostcollector.go | 2 +- .../v1beta2/fake/fake_hostpreflight.go | 2 +- .../v1beta2/fake/fake_preflight.go | 2 +- .../v1beta2/fake/fake_redactor.go | 2 +- .../v1beta2/fake/fake_remotecollector.go | 2 +- .../v1beta2/fake/fake_supportbundle.go | 2 +- .../v1beta2/troubleshoot_client.go | 20 +-------- 16 files changed, 26 insertions(+), 84 deletions(-) diff --git a/pkg/client/troubleshootclientset/clientset.go b/pkg/client/troubleshootclientset/clientset.go index 7af52d4d1..cc5a29168 100644 --- a/pkg/client/troubleshootclientset/clientset.go +++ b/pkg/client/troubleshootclientset/clientset.go @@ -19,7 +19,6 @@ package troubleshootclientset import ( "fmt" - "net/http" troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1" troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2" @@ -34,7 +33,8 @@ type Interface interface { TroubleshootV1beta2() troubleshootv1beta2.TroubleshootV1beta2Interface } -// Clientset contains the clients for groups. +// Clientset contains the clients for groups. Each group has exactly one +// version included in a Clientset. type Clientset struct { *discovery.DiscoveryClient troubleshootV1beta1 *troubleshootv1beta1.TroubleshootV1beta1Client @@ -62,49 +62,26 @@ func (c *Clientset) Discovery() discovery.DiscoveryInterface { // NewForConfig creates a new Clientset for the given config. // If config's RateLimiter is not set and QPS and Burst are acceptable, // NewForConfig will generate a rate-limiter in configShallowCopy. -// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), -// where httpClient was generated with rest.HTTPClientFor(c). func NewForConfig(c *rest.Config) (*Clientset, error) { configShallowCopy := *c - - if configShallowCopy.UserAgent == "" { - configShallowCopy.UserAgent = rest.DefaultKubernetesUserAgent() - } - - // share the transport between all clients - httpClient, err := rest.HTTPClientFor(&configShallowCopy) - if err != nil { - return nil, err - } - - return NewForConfigAndClient(&configShallowCopy, httpClient) -} - -// NewForConfigAndClient creates a new Clientset for the given config and http client. -// Note the http client provided takes precedence over the configured transport values. -// If config's RateLimiter is not set and QPS and Burst are acceptable, -// NewForConfigAndClient will generate a rate-limiter in configShallowCopy. -func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset, error) { - configShallowCopy := *c if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 { if configShallowCopy.Burst <= 0 { return nil, fmt.Errorf("burst is required to be greater than 0 when RateLimiter is not set and QPS is set to greater than 0") } configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst) } - var cs Clientset var err error - cs.troubleshootV1beta1, err = troubleshootv1beta1.NewForConfigAndClient(&configShallowCopy, httpClient) + cs.troubleshootV1beta1, err = troubleshootv1beta1.NewForConfig(&configShallowCopy) if err != nil { return nil, err } - cs.troubleshootV1beta2, err = troubleshootv1beta2.NewForConfigAndClient(&configShallowCopy, httpClient) + cs.troubleshootV1beta2, err = troubleshootv1beta2.NewForConfig(&configShallowCopy) if err != nil { return nil, err } - cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfigAndClient(&configShallowCopy, httpClient) + cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfig(&configShallowCopy) if err != nil { return nil, err } @@ -114,11 +91,12 @@ func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset, // NewForConfigOrDie creates a new Clientset for the given config and // panics if there is an error in the config. func NewForConfigOrDie(c *rest.Config) *Clientset { - cs, err := NewForConfig(c) - if err != nil { - panic(err) - } - return cs + var cs Clientset + cs.troubleshootV1beta1 = troubleshootv1beta1.NewForConfigOrDie(c) + cs.troubleshootV1beta2 = troubleshootv1beta2.NewForConfigOrDie(c) + + cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c) + return &cs } // New creates a new Clientset for the given RESTClient. diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_analyzer.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_analyzer.go index 2661cb460..ec5667589 100644 --- a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_analyzer.go +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_analyzer.go @@ -116,7 +116,7 @@ func (c *FakeAnalyzers) UpdateStatus(ctx context.Context, analyzer *v1beta1.Anal // Delete takes name of the analyzer and deletes it. Returns an error if one occurs. func (c *FakeAnalyzers) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(analyzersResource, c.ns, name, opts), &v1beta1.Analyzer{}) + Invokes(testing.NewDeleteAction(analyzersResource, c.ns, name), &v1beta1.Analyzer{}) return err } diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_collector.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_collector.go index 2a43591ed..8ea3d5ec1 100644 --- a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_collector.go +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_collector.go @@ -116,7 +116,7 @@ func (c *FakeCollectors) UpdateStatus(ctx context.Context, collector *v1beta1.Co // Delete takes name of the collector and deletes it. Returns an error if one occurs. func (c *FakeCollectors) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(collectorsResource, c.ns, name, opts), &v1beta1.Collector{}) + Invokes(testing.NewDeleteAction(collectorsResource, c.ns, name), &v1beta1.Collector{}) return err } diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_preflight.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_preflight.go index 35ddc41a8..9e2724708 100644 --- a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_preflight.go +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_preflight.go @@ -116,7 +116,7 @@ func (c *FakePreflights) UpdateStatus(ctx context.Context, preflight *v1beta1.Pr // Delete takes name of the preflight and deletes it. Returns an error if one occurs. func (c *FakePreflights) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(preflightsResource, c.ns, name, opts), &v1beta1.Preflight{}) + Invokes(testing.NewDeleteAction(preflightsResource, c.ns, name), &v1beta1.Preflight{}) return err } diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_redactor.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_redactor.go index 261d5dd49..3109c7980 100644 --- a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_redactor.go +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_redactor.go @@ -116,7 +116,7 @@ func (c *FakeRedactors) UpdateStatus(ctx context.Context, redactor *v1beta1.Reda // Delete takes name of the redactor and deletes it. Returns an error if one occurs. func (c *FakeRedactors) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(redactorsResource, c.ns, name, opts), &v1beta1.Redactor{}) + Invokes(testing.NewDeleteAction(redactorsResource, c.ns, name), &v1beta1.Redactor{}) return err } diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_supportbundle.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_supportbundle.go index 46d6b3a26..6b4b8e495 100644 --- a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_supportbundle.go +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_supportbundle.go @@ -116,7 +116,7 @@ func (c *FakeSupportBundles) UpdateStatus(ctx context.Context, supportBundle *v1 // Delete takes name of the supportBundle and deletes it. Returns an error if one occurs. func (c *FakeSupportBundles) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(supportbundlesResource, c.ns, name, opts), &v1beta1.SupportBundle{}) + Invokes(testing.NewDeleteAction(supportbundlesResource, c.ns, name), &v1beta1.SupportBundle{}) return err } diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/troubleshoot_client.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/troubleshoot_client.go index 628b5ebc2..8b5b3299b 100644 --- a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/troubleshoot_client.go +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/troubleshoot_client.go @@ -18,8 +18,6 @@ limitations under the License. package v1beta1 import ( - "net/http" - v1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/scheme" rest "k8s.io/client-go/rest" @@ -60,28 +58,12 @@ func (c *TroubleshootV1beta1Client) SupportBundles(namespace string) SupportBund } // NewForConfig creates a new TroubleshootV1beta1Client for the given config. -// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), -// where httpClient was generated with rest.HTTPClientFor(c). func NewForConfig(c *rest.Config) (*TroubleshootV1beta1Client, error) { config := *c if err := setConfigDefaults(&config); err != nil { return nil, err } - httpClient, err := rest.HTTPClientFor(&config) - if err != nil { - return nil, err - } - return NewForConfigAndClient(&config, httpClient) -} - -// NewForConfigAndClient creates a new TroubleshootV1beta1Client for the given config and http client. -// Note the http client provided takes precedence over the configured transport values. -func NewForConfigAndClient(c *rest.Config, h *http.Client) (*TroubleshootV1beta1Client, error) { - config := *c - if err := setConfigDefaults(&config); err != nil { - return nil, err - } - client, err := rest.RESTClientForConfigAndClient(&config, h) + client, err := rest.RESTClientFor(&config) if err != nil { return nil, err } diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_analyzer.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_analyzer.go index c15c4745e..b17f45840 100644 --- a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_analyzer.go +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_analyzer.go @@ -116,7 +116,7 @@ func (c *FakeAnalyzers) UpdateStatus(ctx context.Context, analyzer *v1beta2.Anal // Delete takes name of the analyzer and deletes it. Returns an error if one occurs. func (c *FakeAnalyzers) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(analyzersResource, c.ns, name, opts), &v1beta2.Analyzer{}) + Invokes(testing.NewDeleteAction(analyzersResource, c.ns, name), &v1beta2.Analyzer{}) return err } diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_collector.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_collector.go index 1f9c0053a..d352dd092 100644 --- a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_collector.go +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_collector.go @@ -116,7 +116,7 @@ func (c *FakeCollectors) UpdateStatus(ctx context.Context, collector *v1beta2.Co // Delete takes name of the collector and deletes it. Returns an error if one occurs. func (c *FakeCollectors) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(collectorsResource, c.ns, name, opts), &v1beta2.Collector{}) + Invokes(testing.NewDeleteAction(collectorsResource, c.ns, name), &v1beta2.Collector{}) return err } diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_hostcollector.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_hostcollector.go index cd9d1b6a2..837c7576d 100644 --- a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_hostcollector.go +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_hostcollector.go @@ -116,7 +116,7 @@ func (c *FakeHostCollectors) UpdateStatus(ctx context.Context, hostCollector *v1 // Delete takes name of the hostCollector and deletes it. Returns an error if one occurs. func (c *FakeHostCollectors) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(hostcollectorsResource, c.ns, name, opts), &v1beta2.HostCollector{}) + Invokes(testing.NewDeleteAction(hostcollectorsResource, c.ns, name), &v1beta2.HostCollector{}) return err } diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_hostpreflight.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_hostpreflight.go index 57e5b9071..761fd6d8c 100644 --- a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_hostpreflight.go +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_hostpreflight.go @@ -116,7 +116,7 @@ func (c *FakeHostPreflights) UpdateStatus(ctx context.Context, hostPreflight *v1 // Delete takes name of the hostPreflight and deletes it. Returns an error if one occurs. func (c *FakeHostPreflights) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(hostpreflightsResource, c.ns, name, opts), &v1beta2.HostPreflight{}) + Invokes(testing.NewDeleteAction(hostpreflightsResource, c.ns, name), &v1beta2.HostPreflight{}) return err } diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_preflight.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_preflight.go index a4014d75d..67ee46668 100644 --- a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_preflight.go +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_preflight.go @@ -116,7 +116,7 @@ func (c *FakePreflights) UpdateStatus(ctx context.Context, preflight *v1beta2.Pr // Delete takes name of the preflight and deletes it. Returns an error if one occurs. func (c *FakePreflights) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(preflightsResource, c.ns, name, opts), &v1beta2.Preflight{}) + Invokes(testing.NewDeleteAction(preflightsResource, c.ns, name), &v1beta2.Preflight{}) return err } diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_redactor.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_redactor.go index 3bfbf5fa2..433496600 100644 --- a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_redactor.go +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_redactor.go @@ -116,7 +116,7 @@ func (c *FakeRedactors) UpdateStatus(ctx context.Context, redactor *v1beta2.Reda // Delete takes name of the redactor and deletes it. Returns an error if one occurs. func (c *FakeRedactors) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(redactorsResource, c.ns, name, opts), &v1beta2.Redactor{}) + Invokes(testing.NewDeleteAction(redactorsResource, c.ns, name), &v1beta2.Redactor{}) return err } diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_remotecollector.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_remotecollector.go index a9bcadf88..ae0ddb17d 100644 --- a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_remotecollector.go +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_remotecollector.go @@ -116,7 +116,7 @@ func (c *FakeRemoteCollectors) UpdateStatus(ctx context.Context, remoteCollector // Delete takes name of the remoteCollector and deletes it. Returns an error if one occurs. func (c *FakeRemoteCollectors) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(remotecollectorsResource, c.ns, name, opts), &v1beta2.RemoteCollector{}) + Invokes(testing.NewDeleteAction(remotecollectorsResource, c.ns, name), &v1beta2.RemoteCollector{}) return err } diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_supportbundle.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_supportbundle.go index e71c0cfab..e5cb8ad8f 100644 --- a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_supportbundle.go +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_supportbundle.go @@ -116,7 +116,7 @@ func (c *FakeSupportBundles) UpdateStatus(ctx context.Context, supportBundle *v1 // Delete takes name of the supportBundle and deletes it. Returns an error if one occurs. func (c *FakeSupportBundles) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(supportbundlesResource, c.ns, name, opts), &v1beta2.SupportBundle{}) + Invokes(testing.NewDeleteAction(supportbundlesResource, c.ns, name), &v1beta2.SupportBundle{}) return err } diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/troubleshoot_client.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/troubleshoot_client.go index ae137af92..6c3a0fea8 100644 --- a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/troubleshoot_client.go +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/troubleshoot_client.go @@ -18,8 +18,6 @@ limitations under the License. package v1beta2 import ( - "net/http" - v1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/scheme" rest "k8s.io/client-go/rest" @@ -75,28 +73,12 @@ func (c *TroubleshootV1beta2Client) SupportBundles(namespace string) SupportBund } // NewForConfig creates a new TroubleshootV1beta2Client for the given config. -// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), -// where httpClient was generated with rest.HTTPClientFor(c). func NewForConfig(c *rest.Config) (*TroubleshootV1beta2Client, error) { config := *c if err := setConfigDefaults(&config); err != nil { return nil, err } - httpClient, err := rest.HTTPClientFor(&config) - if err != nil { - return nil, err - } - return NewForConfigAndClient(&config, httpClient) -} - -// NewForConfigAndClient creates a new TroubleshootV1beta2Client for the given config and http client. -// Note the http client provided takes precedence over the configured transport values. -func NewForConfigAndClient(c *rest.Config, h *http.Client) (*TroubleshootV1beta2Client, error) { - config := *c - if err := setConfigDefaults(&config); err != nil { - return nil, err - } - client, err := rest.RESTClientForConfigAndClient(&config, h) + client, err := rest.RESTClientFor(&config) if err != nil { return nil, err } From 8fd8a54d1ac3d0685baa64bf9d3655e4511e194e Mon Sep 17 00:00:00 2001 From: Chase Hainey Date: Tue, 31 Jan 2023 00:48:42 +0000 Subject: [PATCH 13/55] Cleaning up the workspace. --- 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 ++++++++++++ schemas/analyzer-troubleshoot-v1beta2.json | 80 +++++++++++ schemas/collector-troubleshoot-v1beta2.json | 55 +++++++ schemas/preflight-troubleshoot-v1beta2.json | 135 ++++++++++++++++++ .../supportbundle-troubleshoot-v1beta2.json | 135 ++++++++++++++++++ 8 files changed, 669 insertions(+) diff --git a/config/crds/troubleshoot.sh_analyzers.yaml b/config/crds/troubleshoot.sh_analyzers.yaml index 45e696ddd..9231288bb 100644 --- a/config/crds/troubleshoot.sh_analyzers.yaml +++ b/config/crds/troubleshoot.sh_analyzers.yaml @@ -775,6 +775,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 dd176ec65..09451f148 100644 --- a/config/crds/troubleshoot.sh_collectors.yaml +++ b/config/crds/troubleshoot.sh_collectors.yaml @@ -360,6 +360,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 e81f11d91..a4de554cf 100644 --- a/config/crds/troubleshoot.sh_preflights.yaml +++ b/config/crds/troubleshoot.sh_preflights.yaml @@ -775,6 +775,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: @@ -1752,6 +1804,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 7f3250d5d..18e312a5b 100644 --- a/config/crds/troubleshoot.sh_supportbundles.yaml +++ b/config/crds/troubleshoot.sh_supportbundles.yaml @@ -806,6 +806,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: @@ -1783,6 +1835,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/schemas/analyzer-troubleshoot-v1beta2.json b/schemas/analyzer-troubleshoot-v1beta2.json index 87fa17ef3..de20cdcf2 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 7bf2ae9e4..f84dd1dc8 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 d8a702e8b..bf254ebee 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 43407b923..2de4ec2d4 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": [ From fcdb895c9e5c7d50266d6ac42dc3a7fca7204775 Mon Sep 17 00:00:00 2001 From: Chuck D'Antonio Date: Tue, 31 Jan 2023 15:11:31 -0500 Subject: [PATCH 14/55] Updates schemas per PR feedback --- 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 ++++++++++++ schemas/analyzer-troubleshoot-v1beta2.json | 80 +++++++++++ schemas/collector-troubleshoot-v1beta2.json | 55 +++++++ schemas/preflight-troubleshoot-v1beta2.json | 135 ++++++++++++++++++ .../supportbundle-troubleshoot-v1beta2.json | 135 ++++++++++++++++++ 8 files changed, 669 insertions(+) diff --git a/config/crds/troubleshoot.sh_analyzers.yaml b/config/crds/troubleshoot.sh_analyzers.yaml index 45e696ddd..9231288bb 100644 --- a/config/crds/troubleshoot.sh_analyzers.yaml +++ b/config/crds/troubleshoot.sh_analyzers.yaml @@ -775,6 +775,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 dd176ec65..09451f148 100644 --- a/config/crds/troubleshoot.sh_collectors.yaml +++ b/config/crds/troubleshoot.sh_collectors.yaml @@ -360,6 +360,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 e81f11d91..a4de554cf 100644 --- a/config/crds/troubleshoot.sh_preflights.yaml +++ b/config/crds/troubleshoot.sh_preflights.yaml @@ -775,6 +775,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: @@ -1752,6 +1804,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 7f3250d5d..18e312a5b 100644 --- a/config/crds/troubleshoot.sh_supportbundles.yaml +++ b/config/crds/troubleshoot.sh_supportbundles.yaml @@ -806,6 +806,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: @@ -1783,6 +1835,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/schemas/analyzer-troubleshoot-v1beta2.json b/schemas/analyzer-troubleshoot-v1beta2.json index 87fa17ef3..de20cdcf2 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 7bf2ae9e4..f84dd1dc8 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 d8a702e8b..bf254ebee 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 43407b923..2de4ec2d4 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": [ From 91030bf09296d4803fac8f7e8b33db617e5196c0 Mon Sep 17 00:00:00 2001 From: Chase Hainey Date: Fri, 17 Mar 2023 20:05:43 +0000 Subject: [PATCH 15/55] Unit Tests. --- pkg/analyze/mssql_test.go | 117 ++++++++++++++++++++++++++++++++++++++ pkg/collect/mssql_test.go | 45 ++++++++++++--- 2 files changed, 155 insertions(+), 7 deletions(-) create mode 100644 pkg/analyze/mssql_test.go diff --git a/pkg/analyze/mssql_test.go b/pkg/analyze/mssql_test.go new file mode 100644 index 000000000..eb3b312d1 --- /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/collect/mssql_test.go b/pkg/collect/mssql_test.go index ffd8f359f..1b1451655 100644 --- a/pkg/collect/mssql_test.go +++ b/pkg/collect/mssql_test.go @@ -9,23 +9,54 @@ import ( 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", + 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.mssqlVersion, func(t *testing.T) { + t.Run(test.name, func(t *testing.T) { req := require.New(t) actual, err := parseMsSqlVersion(test.mssqlVersion) - req.NoError(err) - + if test.hasError { + req.Error(err) + } else { + req.NoError(err) + } assert.Equal(t, test.expect, actual) }) From f51f4b24ae514454da4b1b2f0d6af3e03b4830ac Mon Sep 17 00:00:00 2001 From: "yunju.lly" Date: Wed, 1 Feb 2023 20:36:15 +0800 Subject: [PATCH 16/55] 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 --- pkg/preflight/concat.go | 32 ++++++++++++++++++++++++-------- pkg/preflight/run.go | 14 +++----------- 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/pkg/preflight/concat.go b/pkg/preflight/concat.go index 28adbb509..5e7dc22b4 100644 --- a/pkg/preflight/concat.go +++ b/pkg/preflight/concat.go @@ -5,17 +5,33 @@ import ( ) func ConcatPreflightSpec(target *troubleshootv1beta2.Preflight, source *troubleshootv1beta2.Preflight) *troubleshootv1beta2.Preflight { - newSpec := target.DeepCopy() - newSpec.Spec.Collectors = append(target.Spec.Collectors, source.Spec.Collectors...) - newSpec.Spec.RemoteCollectors = append(target.Spec.RemoteCollectors, source.Spec.RemoteCollectors...) - newSpec.Spec.Analyzers = append(target.Spec.Analyzers, source.Spec.Analyzers...) + if source == nil { + return target + } + var newSpec *troubleshootv1beta2.Preflight + if target == nil { + newSpec = source + } else { + newSpec = target.DeepCopy() + newSpec.Spec.Collectors = append(newSpec.Spec.Collectors, source.Spec.Collectors...) + newSpec.Spec.RemoteCollectors = append(newSpec.Spec.RemoteCollectors, source.Spec.RemoteCollectors...) + newSpec.Spec.Analyzers = append(newSpec.Spec.Analyzers, source.Spec.Analyzers...) + } return newSpec } func ConcatHostPreflightSpec(target *troubleshootv1beta2.HostPreflight, source *troubleshootv1beta2.HostPreflight) *troubleshootv1beta2.HostPreflight { - newSpec := target.DeepCopy() - newSpec.Spec.Collectors = append(target.Spec.Collectors, source.Spec.Collectors...) - newSpec.Spec.RemoteCollectors = append(target.Spec.RemoteCollectors, source.Spec.RemoteCollectors...) - newSpec.Spec.Analyzers = append(target.Spec.Analyzers, source.Spec.Analyzers...) + if source == nil { + return target + } + var newSpec *troubleshootv1beta2.HostPreflight + if target == nil { + newSpec = source + } else { + newSpec = target.DeepCopy() + newSpec.Spec.Collectors = append(newSpec.Spec.Collectors, source.Spec.Collectors...) + newSpec.Spec.RemoteCollectors = append(newSpec.Spec.RemoteCollectors, source.Spec.RemoteCollectors...) + newSpec.Spec.Analyzers = append(newSpec.Spec.Analyzers, source.Spec.Analyzers...) + } return newSpec } diff --git a/pkg/preflight/run.go b/pkg/preflight/run.go index 40f3e0c9b..9cb246db2 100644 --- a/pkg/preflight/run.go +++ b/pkg/preflight/run.go @@ -49,7 +49,7 @@ func RunPreflights(interactive bool, output string, format string, args []string var uploadResultSpecs []*troubleshootv1beta2.Preflight var err error - for i, v := range args { + for _, v := range args { if strings.HasPrefix(v, "secret/") { // format secret/namespace-name/secret-name pathParts := strings.Split(v, "/") @@ -126,20 +126,12 @@ func RunPreflights(interactive bool, output string, format string, args []string if spec, ok := obj.(*troubleshootv1beta2.Preflight); ok { if spec.Spec.UploadResultsTo == "" { - if i == 0 { - preflightSpec = spec - } else { - preflightSpec = ConcatPreflightSpec(preflightSpec, spec) - } + preflightSpec = ConcatPreflightSpec(preflightSpec, spec) } else { uploadResultSpecs = append(uploadResultSpecs, spec) } } else if spec, ok := obj.(*troubleshootv1beta2.HostPreflight); ok { - if i == 0 { - hostPreflightSpec = spec - } else { - hostPreflightSpec = ConcatHostPreflightSpec(hostPreflightSpec, spec) - } + hostPreflightSpec = ConcatHostPreflightSpec(hostPreflightSpec, spec) } } From dd04684102a6d4174619ca9d248135040f0ec72e Mon Sep 17 00:00:00 2001 From: Camila Macedo <7708031+camilamacedo86@users.noreply.github.com> Date: Wed, 1 Feb 2023 17:06:46 +0000 Subject: [PATCH 17/55] 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 --- Makefile | 4 +- ...troubleshoot.replicated.com_analyzers.yaml | 9 +- ...roubleshoot.replicated.com_collectors.yaml | 9 +- ...roubleshoot.replicated.com_preflights.yaml | 9 +- ...troubleshoot.replicated.com_redactors.yaml | 9 +- ...leshoot.replicated.com_supportbundles.yaml | 9 +- config/crds/troubleshoot.sh_analyzers.yaml | 9 +- config/crds/troubleshoot.sh_collectors.yaml | 103 ++++++++---- .../crds/troubleshoot.sh_hostcollectors.yaml | 9 +- .../crds/troubleshoot.sh_hostpreflights.yaml | 9 +- config/crds/troubleshoot.sh_preflights.yaml | 103 ++++++++---- config/crds/troubleshoot.sh_redactors.yaml | 9 +- .../troubleshoot.sh_remotecollectors.yaml | 9 +- .../crds/troubleshoot.sh_supportbundles.yaml | 103 ++++++++---- schemas/collector-troubleshoot-v1beta2.json | 150 ++++++++++++------ schemas/preflight-troubleshoot-v1beta2.json | 150 ++++++++++++------ .../supportbundle-troubleshoot-v1beta2.json | 150 ++++++++++++------ 17 files changed, 525 insertions(+), 328 deletions(-) diff --git a/Makefile b/Makefile index 0d898c7ca..196004348 100644 --- a/Makefile +++ b/Makefile @@ -124,13 +124,13 @@ docs: fmt vet ./bin/docsgen controller-gen: - go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.7.0 + go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.11.2 CONTROLLER_GEN=$(shell which controller-gen) .PHONY: client-gen client-gen: ifeq (, $(shell which client-gen)) - go install k8s.io/code-generator/cmd/client-gen@v0.22.2 + go install k8s.io/code-generator/cmd/client-gen@v0.26.1 CLIENT_GEN=$(shell go env GOPATH)/bin/client-gen else CLIENT_GEN=$(shell which client-gen) diff --git a/config/crds/troubleshoot.replicated.com_analyzers.yaml b/config/crds/troubleshoot.replicated.com_analyzers.yaml index 3f5a2cabb..7b8aeae73 100644 --- a/config/crds/troubleshoot.replicated.com_analyzers.yaml +++ b/config/crds/troubleshoot.replicated.com_analyzers.yaml @@ -1,10 +1,9 @@ - --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.7.0 + controller-gen.kubebuilder.io/version: v0.11.2 creationTimestamp: null name: analyzers.troubleshoot.replicated.com spec: @@ -746,9 +745,3 @@ spec: type: object served: true storage: true -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/config/crds/troubleshoot.replicated.com_collectors.yaml b/config/crds/troubleshoot.replicated.com_collectors.yaml index 5b5274e3c..835bb8e9f 100644 --- a/config/crds/troubleshoot.replicated.com_collectors.yaml +++ b/config/crds/troubleshoot.replicated.com_collectors.yaml @@ -1,10 +1,9 @@ - --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.7.0 + controller-gen.kubebuilder.io/version: v0.11.2 creationTimestamp: null name: collectors.troubleshoot.replicated.com spec: @@ -329,9 +328,3 @@ spec: type: object served: true storage: true -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/config/crds/troubleshoot.replicated.com_preflights.yaml b/config/crds/troubleshoot.replicated.com_preflights.yaml index 87887cb13..72325f58b 100644 --- a/config/crds/troubleshoot.replicated.com_preflights.yaml +++ b/config/crds/troubleshoot.replicated.com_preflights.yaml @@ -1,10 +1,9 @@ - --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.7.0 + controller-gen.kubebuilder.io/version: v0.11.2 creationTimestamp: null name: preflights.troubleshoot.replicated.com spec: @@ -1003,9 +1002,3 @@ spec: type: object served: true storage: true -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/config/crds/troubleshoot.replicated.com_redactors.yaml b/config/crds/troubleshoot.replicated.com_redactors.yaml index a869ff286..8eed29de7 100644 --- a/config/crds/troubleshoot.replicated.com_redactors.yaml +++ b/config/crds/troubleshoot.replicated.com_redactors.yaml @@ -1,10 +1,9 @@ - --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.7.0 + controller-gen.kubebuilder.io/version: v0.11.2 creationTimestamp: null name: redactors.troubleshoot.replicated.com spec: @@ -79,9 +78,3 @@ spec: type: object served: true storage: true -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/config/crds/troubleshoot.replicated.com_supportbundles.yaml b/config/crds/troubleshoot.replicated.com_supportbundles.yaml index b79e42cde..f423ee0c0 100644 --- a/config/crds/troubleshoot.replicated.com_supportbundles.yaml +++ b/config/crds/troubleshoot.replicated.com_supportbundles.yaml @@ -1,10 +1,9 @@ - --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.7.0 + controller-gen.kubebuilder.io/version: v0.11.2 creationTimestamp: null name: supportbundles.troubleshoot.replicated.com spec: @@ -1032,9 +1031,3 @@ spec: type: object served: true storage: true -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/config/crds/troubleshoot.sh_analyzers.yaml b/config/crds/troubleshoot.sh_analyzers.yaml index 9231288bb..f5b77a777 100644 --- a/config/crds/troubleshoot.sh_analyzers.yaml +++ b/config/crds/troubleshoot.sh_analyzers.yaml @@ -1,10 +1,9 @@ - --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.7.0 + controller-gen.kubebuilder.io/version: v0.11.2 creationTimestamp: null name: analyzers.troubleshoot.sh spec: @@ -2412,9 +2411,3 @@ spec: type: object served: true storage: true -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/config/crds/troubleshoot.sh_collectors.yaml b/config/crds/troubleshoot.sh_collectors.yaml index 09451f148..c832c64bd 100644 --- a/config/crds/troubleshoot.sh_collectors.yaml +++ b/config/crds/troubleshoot.sh_collectors.yaml @@ -1,10 +1,9 @@ - --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.7.0 + controller-gen.kubebuilder.io/version: v0.11.2 creationTimestamp: null name: collectors.troubleshoot.sh spec: @@ -720,6 +719,7 @@ spec: type: object type: array type: object + x-kubernetes-map-type: atomic weight: description: Weight associated with matching the corresponding nodeSelectorTerm, @@ -833,10 +833,12 @@ spec: type: object type: array type: object + x-kubernetes-map-type: atomic type: array required: - nodeSelectorTerms type: object + x-kubernetes-map-type: atomic type: object podAffinity: description: Describes pod affinity scheduling rules @@ -929,6 +931,7 @@ spec: are ANDed. type: object type: object + x-kubernetes-map-type: atomic namespaceSelector: description: A label query over the set of namespaces that the term @@ -998,6 +1001,7 @@ spec: are ANDed. type: object type: object + x-kubernetes-map-type: atomic namespaces: description: namespaces specifies a static list of namespace names @@ -1117,6 +1121,7 @@ spec: ANDed. type: object type: object + x-kubernetes-map-type: atomic namespaceSelector: description: A label query over the set of namespaces that the term applies @@ -1180,6 +1185,7 @@ spec: ANDed. type: object type: object + x-kubernetes-map-type: atomic namespaces: description: namespaces specifies a static list of namespace names that the term @@ -1300,6 +1306,7 @@ spec: are ANDed. type: object type: object + x-kubernetes-map-type: atomic namespaceSelector: description: A label query over the set of namespaces that the term @@ -1369,6 +1376,7 @@ spec: are ANDed. type: object type: object + x-kubernetes-map-type: atomic namespaces: description: namespaces specifies a static list of namespace names @@ -1488,6 +1496,7 @@ spec: ANDed. type: object type: object + x-kubernetes-map-type: atomic namespaceSelector: description: A label query over the set of namespaces that the term applies @@ -1551,6 +1560,7 @@ spec: ANDed. type: object type: object + x-kubernetes-map-type: atomic namespaces: description: namespaces specifies a static list of namespace names that the term @@ -1676,6 +1686,7 @@ spec: required: - key type: object + x-kubernetes-map-type: atomic fieldRef: description: 'Selects a field of the pod: supports metadata.name, metadata.namespace, @@ -1695,6 +1706,7 @@ spec: required: - fieldPath type: object + x-kubernetes-map-type: atomic resourceFieldRef: description: 'Selects a resource of the container: only resources limits @@ -1724,6 +1736,7 @@ spec: required: - resource type: object + x-kubernetes-map-type: atomic secretKeyRef: description: Selects a key of a secret in the pod's namespace @@ -1746,6 +1759,7 @@ spec: required: - key type: object + x-kubernetes-map-type: atomic type: object required: - name @@ -1779,6 +1793,7 @@ spec: must be defined type: boolean type: object + x-kubernetes-map-type: atomic prefix: description: An optional identifier to prepend to each key in the ConfigMap. Must be @@ -1798,6 +1813,7 @@ spec: must be defined type: boolean type: object + x-kubernetes-map-type: atomic type: object type: array image: @@ -3154,6 +3170,7 @@ spec: required: - key type: object + x-kubernetes-map-type: atomic fieldRef: description: 'Selects a field of the pod: supports metadata.name, metadata.namespace, @@ -3173,6 +3190,7 @@ spec: required: - fieldPath type: object + x-kubernetes-map-type: atomic resourceFieldRef: description: 'Selects a resource of the container: only resources limits @@ -3202,6 +3220,7 @@ spec: required: - resource type: object + x-kubernetes-map-type: atomic secretKeyRef: description: Selects a key of a secret in the pod's namespace @@ -3224,6 +3243,7 @@ spec: required: - key type: object + x-kubernetes-map-type: atomic type: object required: - name @@ -3257,6 +3277,7 @@ spec: must be defined type: boolean type: object + x-kubernetes-map-type: atomic prefix: description: An optional identifier to prepend to each key in the ConfigMap. Must be @@ -3276,6 +3297,7 @@ spec: must be defined type: boolean type: object + x-kubernetes-map-type: atomic type: object type: array image: @@ -4537,6 +4559,7 @@ spec: uid?' type: string type: object + x-kubernetes-map-type: atomic type: array initContainers: description: 'List of initialization containers belonging @@ -4641,6 +4664,7 @@ spec: required: - key type: object + x-kubernetes-map-type: atomic fieldRef: description: 'Selects a field of the pod: supports metadata.name, metadata.namespace, @@ -4660,6 +4684,7 @@ spec: required: - fieldPath type: object + x-kubernetes-map-type: atomic resourceFieldRef: description: 'Selects a resource of the container: only resources limits @@ -4689,6 +4714,7 @@ spec: required: - resource type: object + x-kubernetes-map-type: atomic secretKeyRef: description: Selects a key of a secret in the pod's namespace @@ -4711,6 +4737,7 @@ spec: required: - key type: object + x-kubernetes-map-type: atomic type: object required: - name @@ -4744,6 +4771,7 @@ spec: must be defined type: boolean type: object + x-kubernetes-map-type: atomic prefix: description: An optional identifier to prepend to each key in the ConfigMap. Must be @@ -4763,6 +4791,7 @@ spec: must be defined type: boolean type: object + x-kubernetes-map-type: atomic type: object type: array image: @@ -6524,6 +6553,7 @@ spec: "value". The requirements are ANDed. type: object type: object + x-kubernetes-map-type: atomic matchLabelKeys: description: MatchLabelKeys is a set of pod label keys to select the pods over which spreading @@ -6642,12 +6672,12 @@ spec: spread constraint. - DoNotSchedule (default) tells the scheduler not to schedule it. - ScheduleAnyway tells the scheduler to schedule the pod in any - location, but giving higher precedence to - topologies that would help reduce the skew. - A constraint is considered "Unsatisfiable" for - an incoming pod if and only if every possible - node assignment for that pod would violate "MaxSkew" - on some topology. For example, in a 3-zone cluster, + location, but giving higher precedence to topologies + that would help reduce the skew. A constraint + is considered "Unsatisfiable" for an incoming + pod if and only if every possible node assignment + for that pod would violate "MaxSkew" on some + topology. For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same labelSelector spread as 3/1/1: | zone1 | zone2 | zone3 | | P P P | P | P | If WhenUnsatisfiable @@ -6818,6 +6848,7 @@ spec: kind, uid?' type: string type: object + x-kubernetes-map-type: atomic user: description: 'user is optional: User is the rados user name, default is admin More info: @@ -6856,6 +6887,7 @@ spec: kind, uid?' type: string type: object + x-kubernetes-map-type: atomic volumeID: description: 'volumeID used to identify the volume in cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' @@ -6940,6 +6972,7 @@ spec: ConfigMap or its keys must be defined type: boolean type: object + x-kubernetes-map-type: atomic csi: description: csi (Container Storage Interface) represents ephemeral storage that is handled @@ -6975,6 +7008,7 @@ spec: kind, uid?' type: string type: object + x-kubernetes-map-type: atomic readOnly: description: readOnly specifies a read-only configuration for the volume. Defaults to @@ -7036,6 +7070,7 @@ spec: required: - fieldPath type: object + x-kubernetes-map-type: atomic mode: description: 'Optional: mode bits used to set permissions on this file, must @@ -7087,6 +7122,7 @@ spec: required: - resource type: object + x-kubernetes-map-type: atomic required: - path type: object @@ -7129,13 +7165,13 @@ spec: and deleted when the pod is removed. \n Use this if: a) the volume is only needed while the pod runs, b) features of normal volumes - like restoring from snapshot or capacity tracking + like restoring from snapshot or capacity tracking are needed, c) the storage driver is specified through a storage class, and d) the storage driver supports dynamic volume provisioning - through a PersistentVolumeClaim (see EphemeralVolumeSource - for more information on the connection between - this volume type and PersistentVolumeClaim). + through a PersistentVolumeClaim (see EphemeralVolumeSource + for more information on the connection between + this volume type and PersistentVolumeClaim). \n Use PersistentVolumeClaim or one of the vendor-specific APIs for volumes that persist for longer than the lifecycle of an individual pod. \n Use CSI @@ -7234,6 +7270,7 @@ spec: - kind - name type: object + x-kubernetes-map-type: atomic dataSourceRef: description: 'dataSourceRef specifies the object from which to populate @@ -7262,19 +7299,19 @@ spec: differences between dataSource and dataSourceRef: * While dataSource only allows two specific types of - objects, dataSourceRef allows - any non-core object, as well as - PersistentVolumeClaim objects. * - While dataSource ignores disallowed - values (dropping them), dataSourceRef preserves - all values, and generates an error - if a disallowed value is specified. - * While dataSource only allows local - objects, dataSourceRef allows objects in - any namespaces. (Beta) Using this - field requires the AnyVolumeDataSource - feature gate to be enabled. (Alpha) - Using the namespace field of dataSourceRef + objects, dataSourceRef allows any + non-core object, as well as PersistentVolumeClaim + objects. * While dataSource ignores + disallowed values (dropping them), + dataSourceRef preserves all values, + and generates an error if a disallowed + value is specified. * While dataSource + only allows local objects, dataSourceRef + allows objects in any namespaces. + (Beta) Using this field requires + the AnyVolumeDataSource feature + gate to be enabled. (Alpha) Using + the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled.' properties: @@ -7442,6 +7479,7 @@ spec: are ANDed. type: object type: object + x-kubernetes-map-type: atomic storageClassName: description: 'storageClassName is the name of the StorageClass required @@ -7545,6 +7583,7 @@ spec: kind, uid?' type: string type: object + x-kubernetes-map-type: atomic required: - driver type: object @@ -7747,6 +7786,7 @@ spec: kind, uid?' type: string type: object + x-kubernetes-map-type: atomic targetPortal: description: targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port @@ -7943,6 +7983,7 @@ spec: be defined type: boolean type: object + x-kubernetes-map-type: atomic downwardAPI: description: downwardAPI information about the downwardAPI data to project @@ -7976,6 +8017,7 @@ spec: required: - fieldPath type: object + x-kubernetes-map-type: atomic mode: description: 'Optional: mode bits used to set permissions @@ -8036,6 +8078,7 @@ spec: required: - resource type: object + x-kubernetes-map-type: atomic required: - path type: object @@ -8114,6 +8157,7 @@ spec: must be defined type: boolean type: object + x-kubernetes-map-type: atomic serviceAccountToken: description: serviceAccountToken is information about the serviceAccountToken @@ -8246,6 +8290,7 @@ spec: kind, uid?' type: string type: object + x-kubernetes-map-type: atomic user: description: 'user is the rados user name. Default is admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' @@ -8291,6 +8336,7 @@ spec: kind, uid?' type: string type: object + x-kubernetes-map-type: atomic sslEnabled: description: sslEnabled Flag enable/disable SSL communication with Gateway, default @@ -8423,6 +8469,7 @@ spec: kind, uid?' type: string type: object + x-kubernetes-map-type: atomic volumeName: description: volumeName is the human-readable name of the StorageOS volume. Volume names @@ -8540,9 +8587,3 @@ spec: type: object served: true storage: true -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/config/crds/troubleshoot.sh_hostcollectors.yaml b/config/crds/troubleshoot.sh_hostcollectors.yaml index 913d2151b..df2bfe634 100644 --- a/config/crds/troubleshoot.sh_hostcollectors.yaml +++ b/config/crds/troubleshoot.sh_hostcollectors.yaml @@ -1,10 +1,9 @@ - --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.7.0 + controller-gen.kubebuilder.io/version: v0.11.2 creationTimestamp: null name: hostcollectors.troubleshoot.sh spec: @@ -1315,9 +1314,3 @@ spec: type: object served: true storage: true -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/config/crds/troubleshoot.sh_hostpreflights.yaml b/config/crds/troubleshoot.sh_hostpreflights.yaml index 8dae99b05..5725cbd31 100644 --- a/config/crds/troubleshoot.sh_hostpreflights.yaml +++ b/config/crds/troubleshoot.sh_hostpreflights.yaml @@ -1,10 +1,9 @@ - --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.7.0 + controller-gen.kubebuilder.io/version: v0.11.2 creationTimestamp: null name: hostpreflights.troubleshoot.sh spec: @@ -1603,9 +1602,3 @@ spec: type: object served: true storage: true -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/config/crds/troubleshoot.sh_preflights.yaml b/config/crds/troubleshoot.sh_preflights.yaml index a4de554cf..89c5cc3a8 100644 --- a/config/crds/troubleshoot.sh_preflights.yaml +++ b/config/crds/troubleshoot.sh_preflights.yaml @@ -1,10 +1,9 @@ - --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.7.0 + controller-gen.kubebuilder.io/version: v0.11.2 creationTimestamp: null name: preflights.troubleshoot.sh spec: @@ -2164,6 +2163,7 @@ spec: type: object type: array type: object + x-kubernetes-map-type: atomic weight: description: Weight associated with matching the corresponding nodeSelectorTerm, @@ -2277,10 +2277,12 @@ spec: type: object type: array type: object + x-kubernetes-map-type: atomic type: array required: - nodeSelectorTerms type: object + x-kubernetes-map-type: atomic type: object podAffinity: description: Describes pod affinity scheduling rules @@ -2373,6 +2375,7 @@ spec: are ANDed. type: object type: object + x-kubernetes-map-type: atomic namespaceSelector: description: A label query over the set of namespaces that the term @@ -2442,6 +2445,7 @@ spec: are ANDed. type: object type: object + x-kubernetes-map-type: atomic namespaces: description: namespaces specifies a static list of namespace names @@ -2561,6 +2565,7 @@ spec: ANDed. type: object type: object + x-kubernetes-map-type: atomic namespaceSelector: description: A label query over the set of namespaces that the term applies @@ -2624,6 +2629,7 @@ spec: ANDed. type: object type: object + x-kubernetes-map-type: atomic namespaces: description: namespaces specifies a static list of namespace names that the term @@ -2744,6 +2750,7 @@ spec: are ANDed. type: object type: object + x-kubernetes-map-type: atomic namespaceSelector: description: A label query over the set of namespaces that the term @@ -2813,6 +2820,7 @@ spec: are ANDed. type: object type: object + x-kubernetes-map-type: atomic namespaces: description: namespaces specifies a static list of namespace names @@ -2932,6 +2940,7 @@ spec: ANDed. type: object type: object + x-kubernetes-map-type: atomic namespaceSelector: description: A label query over the set of namespaces that the term applies @@ -2995,6 +3004,7 @@ spec: ANDed. type: object type: object + x-kubernetes-map-type: atomic namespaces: description: namespaces specifies a static list of namespace names that the term @@ -3120,6 +3130,7 @@ spec: required: - key type: object + x-kubernetes-map-type: atomic fieldRef: description: 'Selects a field of the pod: supports metadata.name, metadata.namespace, @@ -3139,6 +3150,7 @@ spec: required: - fieldPath type: object + x-kubernetes-map-type: atomic resourceFieldRef: description: 'Selects a resource of the container: only resources limits @@ -3168,6 +3180,7 @@ spec: required: - resource type: object + x-kubernetes-map-type: atomic secretKeyRef: description: Selects a key of a secret in the pod's namespace @@ -3190,6 +3203,7 @@ spec: required: - key type: object + x-kubernetes-map-type: atomic type: object required: - name @@ -3223,6 +3237,7 @@ spec: must be defined type: boolean type: object + x-kubernetes-map-type: atomic prefix: description: An optional identifier to prepend to each key in the ConfigMap. Must be @@ -3242,6 +3257,7 @@ spec: must be defined type: boolean type: object + x-kubernetes-map-type: atomic type: object type: array image: @@ -4598,6 +4614,7 @@ spec: required: - key type: object + x-kubernetes-map-type: atomic fieldRef: description: 'Selects a field of the pod: supports metadata.name, metadata.namespace, @@ -4617,6 +4634,7 @@ spec: required: - fieldPath type: object + x-kubernetes-map-type: atomic resourceFieldRef: description: 'Selects a resource of the container: only resources limits @@ -4646,6 +4664,7 @@ spec: required: - resource type: object + x-kubernetes-map-type: atomic secretKeyRef: description: Selects a key of a secret in the pod's namespace @@ -4668,6 +4687,7 @@ spec: required: - key type: object + x-kubernetes-map-type: atomic type: object required: - name @@ -4701,6 +4721,7 @@ spec: must be defined type: boolean type: object + x-kubernetes-map-type: atomic prefix: description: An optional identifier to prepend to each key in the ConfigMap. Must be @@ -4720,6 +4741,7 @@ spec: must be defined type: boolean type: object + x-kubernetes-map-type: atomic type: object type: array image: @@ -5981,6 +6003,7 @@ spec: uid?' type: string type: object + x-kubernetes-map-type: atomic type: array initContainers: description: 'List of initialization containers belonging @@ -6085,6 +6108,7 @@ spec: required: - key type: object + x-kubernetes-map-type: atomic fieldRef: description: 'Selects a field of the pod: supports metadata.name, metadata.namespace, @@ -6104,6 +6128,7 @@ spec: required: - fieldPath type: object + x-kubernetes-map-type: atomic resourceFieldRef: description: 'Selects a resource of the container: only resources limits @@ -6133,6 +6158,7 @@ spec: required: - resource type: object + x-kubernetes-map-type: atomic secretKeyRef: description: Selects a key of a secret in the pod's namespace @@ -6155,6 +6181,7 @@ spec: required: - key type: object + x-kubernetes-map-type: atomic type: object required: - name @@ -6188,6 +6215,7 @@ spec: must be defined type: boolean type: object + x-kubernetes-map-type: atomic prefix: description: An optional identifier to prepend to each key in the ConfigMap. Must be @@ -6207,6 +6235,7 @@ spec: must be defined type: boolean type: object + x-kubernetes-map-type: atomic type: object type: array image: @@ -7968,6 +7997,7 @@ spec: "value". The requirements are ANDed. type: object type: object + x-kubernetes-map-type: atomic matchLabelKeys: description: MatchLabelKeys is a set of pod label keys to select the pods over which spreading @@ -8086,12 +8116,12 @@ spec: spread constraint. - DoNotSchedule (default) tells the scheduler not to schedule it. - ScheduleAnyway tells the scheduler to schedule the pod in any - location, but giving higher precedence to - topologies that would help reduce the skew. - A constraint is considered "Unsatisfiable" for - an incoming pod if and only if every possible - node assignment for that pod would violate "MaxSkew" - on some topology. For example, in a 3-zone cluster, + location, but giving higher precedence to topologies + that would help reduce the skew. A constraint + is considered "Unsatisfiable" for an incoming + pod if and only if every possible node assignment + for that pod would violate "MaxSkew" on some + topology. For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same labelSelector spread as 3/1/1: | zone1 | zone2 | zone3 | | P P P | P | P | If WhenUnsatisfiable @@ -8262,6 +8292,7 @@ spec: kind, uid?' type: string type: object + x-kubernetes-map-type: atomic user: description: 'user is optional: User is the rados user name, default is admin More info: @@ -8300,6 +8331,7 @@ spec: kind, uid?' type: string type: object + x-kubernetes-map-type: atomic volumeID: description: 'volumeID used to identify the volume in cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' @@ -8384,6 +8416,7 @@ spec: ConfigMap or its keys must be defined type: boolean type: object + x-kubernetes-map-type: atomic csi: description: csi (Container Storage Interface) represents ephemeral storage that is handled @@ -8419,6 +8452,7 @@ spec: kind, uid?' type: string type: object + x-kubernetes-map-type: atomic readOnly: description: readOnly specifies a read-only configuration for the volume. Defaults to @@ -8480,6 +8514,7 @@ spec: required: - fieldPath type: object + x-kubernetes-map-type: atomic mode: description: 'Optional: mode bits used to set permissions on this file, must @@ -8531,6 +8566,7 @@ spec: required: - resource type: object + x-kubernetes-map-type: atomic required: - path type: object @@ -8573,13 +8609,13 @@ spec: and deleted when the pod is removed. \n Use this if: a) the volume is only needed while the pod runs, b) features of normal volumes - like restoring from snapshot or capacity tracking + like restoring from snapshot or capacity tracking are needed, c) the storage driver is specified through a storage class, and d) the storage driver supports dynamic volume provisioning - through a PersistentVolumeClaim (see EphemeralVolumeSource - for more information on the connection between - this volume type and PersistentVolumeClaim). + through a PersistentVolumeClaim (see EphemeralVolumeSource + for more information on the connection between + this volume type and PersistentVolumeClaim). \n Use PersistentVolumeClaim or one of the vendor-specific APIs for volumes that persist for longer than the lifecycle of an individual pod. \n Use CSI @@ -8678,6 +8714,7 @@ spec: - kind - name type: object + x-kubernetes-map-type: atomic dataSourceRef: description: 'dataSourceRef specifies the object from which to populate @@ -8706,19 +8743,19 @@ spec: differences between dataSource and dataSourceRef: * While dataSource only allows two specific types of - objects, dataSourceRef allows - any non-core object, as well as - PersistentVolumeClaim objects. * - While dataSource ignores disallowed - values (dropping them), dataSourceRef preserves - all values, and generates an error - if a disallowed value is specified. - * While dataSource only allows local - objects, dataSourceRef allows objects in - any namespaces. (Beta) Using this - field requires the AnyVolumeDataSource - feature gate to be enabled. (Alpha) - Using the namespace field of dataSourceRef + objects, dataSourceRef allows any + non-core object, as well as PersistentVolumeClaim + objects. * While dataSource ignores + disallowed values (dropping them), + dataSourceRef preserves all values, + and generates an error if a disallowed + value is specified. * While dataSource + only allows local objects, dataSourceRef + allows objects in any namespaces. + (Beta) Using this field requires + the AnyVolumeDataSource feature + gate to be enabled. (Alpha) Using + the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled.' properties: @@ -8886,6 +8923,7 @@ spec: are ANDed. type: object type: object + x-kubernetes-map-type: atomic storageClassName: description: 'storageClassName is the name of the StorageClass required @@ -8989,6 +9027,7 @@ spec: kind, uid?' type: string type: object + x-kubernetes-map-type: atomic required: - driver type: object @@ -9191,6 +9230,7 @@ spec: kind, uid?' type: string type: object + x-kubernetes-map-type: atomic targetPortal: description: targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port @@ -9387,6 +9427,7 @@ spec: be defined type: boolean type: object + x-kubernetes-map-type: atomic downwardAPI: description: downwardAPI information about the downwardAPI data to project @@ -9420,6 +9461,7 @@ spec: required: - fieldPath type: object + x-kubernetes-map-type: atomic mode: description: 'Optional: mode bits used to set permissions @@ -9480,6 +9522,7 @@ spec: required: - resource type: object + x-kubernetes-map-type: atomic required: - path type: object @@ -9558,6 +9601,7 @@ spec: must be defined type: boolean type: object + x-kubernetes-map-type: atomic serviceAccountToken: description: serviceAccountToken is information about the serviceAccountToken @@ -9690,6 +9734,7 @@ spec: kind, uid?' type: string type: object + x-kubernetes-map-type: atomic user: description: 'user is the rados user name. Default is admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' @@ -9735,6 +9780,7 @@ spec: kind, uid?' type: string type: object + x-kubernetes-map-type: atomic sslEnabled: description: sslEnabled Flag enable/disable SSL communication with Gateway, default @@ -9867,6 +9913,7 @@ spec: kind, uid?' type: string type: object + x-kubernetes-map-type: atomic volumeName: description: volumeName is the human-readable name of the StorageOS volume. Volume names @@ -10274,9 +10321,3 @@ spec: type: object served: true storage: true -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/config/crds/troubleshoot.sh_redactors.yaml b/config/crds/troubleshoot.sh_redactors.yaml index 03c65a9f1..97014fb3d 100644 --- a/config/crds/troubleshoot.sh_redactors.yaml +++ b/config/crds/troubleshoot.sh_redactors.yaml @@ -1,10 +1,9 @@ - --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.7.0 + controller-gen.kubebuilder.io/version: v0.11.2 creationTimestamp: null name: redactors.troubleshoot.sh spec: @@ -79,9 +78,3 @@ spec: type: object served: true storage: true -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/config/crds/troubleshoot.sh_remotecollectors.yaml b/config/crds/troubleshoot.sh_remotecollectors.yaml index b7626a606..6a20532a9 100644 --- a/config/crds/troubleshoot.sh_remotecollectors.yaml +++ b/config/crds/troubleshoot.sh_remotecollectors.yaml @@ -1,10 +1,9 @@ - --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.7.0 + controller-gen.kubebuilder.io/version: v0.11.2 creationTimestamp: null name: remotecollectors.troubleshoot.sh spec: @@ -366,9 +365,3 @@ spec: type: object served: true storage: true -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/config/crds/troubleshoot.sh_supportbundles.yaml b/config/crds/troubleshoot.sh_supportbundles.yaml index 18e312a5b..2a03311dd 100644 --- a/config/crds/troubleshoot.sh_supportbundles.yaml +++ b/config/crds/troubleshoot.sh_supportbundles.yaml @@ -1,10 +1,9 @@ - --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.7.0 + controller-gen.kubebuilder.io/version: v0.11.2 creationTimestamp: null name: supportbundles.troubleshoot.sh spec: @@ -2195,6 +2194,7 @@ spec: type: object type: array type: object + x-kubernetes-map-type: atomic weight: description: Weight associated with matching the corresponding nodeSelectorTerm, @@ -2308,10 +2308,12 @@ spec: type: object type: array type: object + x-kubernetes-map-type: atomic type: array required: - nodeSelectorTerms type: object + x-kubernetes-map-type: atomic type: object podAffinity: description: Describes pod affinity scheduling rules @@ -2404,6 +2406,7 @@ spec: are ANDed. type: object type: object + x-kubernetes-map-type: atomic namespaceSelector: description: A label query over the set of namespaces that the term @@ -2473,6 +2476,7 @@ spec: are ANDed. type: object type: object + x-kubernetes-map-type: atomic namespaces: description: namespaces specifies a static list of namespace names @@ -2592,6 +2596,7 @@ spec: ANDed. type: object type: object + x-kubernetes-map-type: atomic namespaceSelector: description: A label query over the set of namespaces that the term applies @@ -2655,6 +2660,7 @@ spec: ANDed. type: object type: object + x-kubernetes-map-type: atomic namespaces: description: namespaces specifies a static list of namespace names that the term @@ -2775,6 +2781,7 @@ spec: are ANDed. type: object type: object + x-kubernetes-map-type: atomic namespaceSelector: description: A label query over the set of namespaces that the term @@ -2844,6 +2851,7 @@ spec: are ANDed. type: object type: object + x-kubernetes-map-type: atomic namespaces: description: namespaces specifies a static list of namespace names @@ -2963,6 +2971,7 @@ spec: ANDed. type: object type: object + x-kubernetes-map-type: atomic namespaceSelector: description: A label query over the set of namespaces that the term applies @@ -3026,6 +3035,7 @@ spec: ANDed. type: object type: object + x-kubernetes-map-type: atomic namespaces: description: namespaces specifies a static list of namespace names that the term @@ -3151,6 +3161,7 @@ spec: required: - key type: object + x-kubernetes-map-type: atomic fieldRef: description: 'Selects a field of the pod: supports metadata.name, metadata.namespace, @@ -3170,6 +3181,7 @@ spec: required: - fieldPath type: object + x-kubernetes-map-type: atomic resourceFieldRef: description: 'Selects a resource of the container: only resources limits @@ -3199,6 +3211,7 @@ spec: required: - resource type: object + x-kubernetes-map-type: atomic secretKeyRef: description: Selects a key of a secret in the pod's namespace @@ -3221,6 +3234,7 @@ spec: required: - key type: object + x-kubernetes-map-type: atomic type: object required: - name @@ -3254,6 +3268,7 @@ spec: must be defined type: boolean type: object + x-kubernetes-map-type: atomic prefix: description: An optional identifier to prepend to each key in the ConfigMap. Must be @@ -3273,6 +3288,7 @@ spec: must be defined type: boolean type: object + x-kubernetes-map-type: atomic type: object type: array image: @@ -4629,6 +4645,7 @@ spec: required: - key type: object + x-kubernetes-map-type: atomic fieldRef: description: 'Selects a field of the pod: supports metadata.name, metadata.namespace, @@ -4648,6 +4665,7 @@ spec: required: - fieldPath type: object + x-kubernetes-map-type: atomic resourceFieldRef: description: 'Selects a resource of the container: only resources limits @@ -4677,6 +4695,7 @@ spec: required: - resource type: object + x-kubernetes-map-type: atomic secretKeyRef: description: Selects a key of a secret in the pod's namespace @@ -4699,6 +4718,7 @@ spec: required: - key type: object + x-kubernetes-map-type: atomic type: object required: - name @@ -4732,6 +4752,7 @@ spec: must be defined type: boolean type: object + x-kubernetes-map-type: atomic prefix: description: An optional identifier to prepend to each key in the ConfigMap. Must be @@ -4751,6 +4772,7 @@ spec: must be defined type: boolean type: object + x-kubernetes-map-type: atomic type: object type: array image: @@ -6012,6 +6034,7 @@ spec: uid?' type: string type: object + x-kubernetes-map-type: atomic type: array initContainers: description: 'List of initialization containers belonging @@ -6116,6 +6139,7 @@ spec: required: - key type: object + x-kubernetes-map-type: atomic fieldRef: description: 'Selects a field of the pod: supports metadata.name, metadata.namespace, @@ -6135,6 +6159,7 @@ spec: required: - fieldPath type: object + x-kubernetes-map-type: atomic resourceFieldRef: description: 'Selects a resource of the container: only resources limits @@ -6164,6 +6189,7 @@ spec: required: - resource type: object + x-kubernetes-map-type: atomic secretKeyRef: description: Selects a key of a secret in the pod's namespace @@ -6186,6 +6212,7 @@ spec: required: - key type: object + x-kubernetes-map-type: atomic type: object required: - name @@ -6219,6 +6246,7 @@ spec: must be defined type: boolean type: object + x-kubernetes-map-type: atomic prefix: description: An optional identifier to prepend to each key in the ConfigMap. Must be @@ -6238,6 +6266,7 @@ spec: must be defined type: boolean type: object + x-kubernetes-map-type: atomic type: object type: array image: @@ -7999,6 +8028,7 @@ spec: "value". The requirements are ANDed. type: object type: object + x-kubernetes-map-type: atomic matchLabelKeys: description: MatchLabelKeys is a set of pod label keys to select the pods over which spreading @@ -8117,12 +8147,12 @@ spec: spread constraint. - DoNotSchedule (default) tells the scheduler not to schedule it. - ScheduleAnyway tells the scheduler to schedule the pod in any - location, but giving higher precedence to - topologies that would help reduce the skew. - A constraint is considered "Unsatisfiable" for - an incoming pod if and only if every possible - node assignment for that pod would violate "MaxSkew" - on some topology. For example, in a 3-zone cluster, + location, but giving higher precedence to topologies + that would help reduce the skew. A constraint + is considered "Unsatisfiable" for an incoming + pod if and only if every possible node assignment + for that pod would violate "MaxSkew" on some + topology. For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same labelSelector spread as 3/1/1: | zone1 | zone2 | zone3 | | P P P | P | P | If WhenUnsatisfiable @@ -8293,6 +8323,7 @@ spec: kind, uid?' type: string type: object + x-kubernetes-map-type: atomic user: description: 'user is optional: User is the rados user name, default is admin More info: @@ -8331,6 +8362,7 @@ spec: kind, uid?' type: string type: object + x-kubernetes-map-type: atomic volumeID: description: 'volumeID used to identify the volume in cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' @@ -8415,6 +8447,7 @@ spec: ConfigMap or its keys must be defined type: boolean type: object + x-kubernetes-map-type: atomic csi: description: csi (Container Storage Interface) represents ephemeral storage that is handled @@ -8450,6 +8483,7 @@ spec: kind, uid?' type: string type: object + x-kubernetes-map-type: atomic readOnly: description: readOnly specifies a read-only configuration for the volume. Defaults to @@ -8511,6 +8545,7 @@ spec: required: - fieldPath type: object + x-kubernetes-map-type: atomic mode: description: 'Optional: mode bits used to set permissions on this file, must @@ -8562,6 +8597,7 @@ spec: required: - resource type: object + x-kubernetes-map-type: atomic required: - path type: object @@ -8604,13 +8640,13 @@ spec: and deleted when the pod is removed. \n Use this if: a) the volume is only needed while the pod runs, b) features of normal volumes - like restoring from snapshot or capacity tracking + like restoring from snapshot or capacity tracking are needed, c) the storage driver is specified through a storage class, and d) the storage driver supports dynamic volume provisioning - through a PersistentVolumeClaim (see EphemeralVolumeSource - for more information on the connection between - this volume type and PersistentVolumeClaim). + through a PersistentVolumeClaim (see EphemeralVolumeSource + for more information on the connection between + this volume type and PersistentVolumeClaim). \n Use PersistentVolumeClaim or one of the vendor-specific APIs for volumes that persist for longer than the lifecycle of an individual pod. \n Use CSI @@ -8709,6 +8745,7 @@ spec: - kind - name type: object + x-kubernetes-map-type: atomic dataSourceRef: description: 'dataSourceRef specifies the object from which to populate @@ -8737,19 +8774,19 @@ spec: differences between dataSource and dataSourceRef: * While dataSource only allows two specific types of - objects, dataSourceRef allows - any non-core object, as well as - PersistentVolumeClaim objects. * - While dataSource ignores disallowed - values (dropping them), dataSourceRef preserves - all values, and generates an error - if a disallowed value is specified. - * While dataSource only allows local - objects, dataSourceRef allows objects in - any namespaces. (Beta) Using this - field requires the AnyVolumeDataSource - feature gate to be enabled. (Alpha) - Using the namespace field of dataSourceRef + objects, dataSourceRef allows any + non-core object, as well as PersistentVolumeClaim + objects. * While dataSource ignores + disallowed values (dropping them), + dataSourceRef preserves all values, + and generates an error if a disallowed + value is specified. * While dataSource + only allows local objects, dataSourceRef + allows objects in any namespaces. + (Beta) Using this field requires + the AnyVolumeDataSource feature + gate to be enabled. (Alpha) Using + the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled.' properties: @@ -8917,6 +8954,7 @@ spec: are ANDed. type: object type: object + x-kubernetes-map-type: atomic storageClassName: description: 'storageClassName is the name of the StorageClass required @@ -9020,6 +9058,7 @@ spec: kind, uid?' type: string type: object + x-kubernetes-map-type: atomic required: - driver type: object @@ -9222,6 +9261,7 @@ spec: kind, uid?' type: string type: object + x-kubernetes-map-type: atomic targetPortal: description: targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port @@ -9418,6 +9458,7 @@ spec: be defined type: boolean type: object + x-kubernetes-map-type: atomic downwardAPI: description: downwardAPI information about the downwardAPI data to project @@ -9451,6 +9492,7 @@ spec: required: - fieldPath type: object + x-kubernetes-map-type: atomic mode: description: 'Optional: mode bits used to set permissions @@ -9511,6 +9553,7 @@ spec: required: - resource type: object + x-kubernetes-map-type: atomic required: - path type: object @@ -9589,6 +9632,7 @@ spec: must be defined type: boolean type: object + x-kubernetes-map-type: atomic serviceAccountToken: description: serviceAccountToken is information about the serviceAccountToken @@ -9721,6 +9765,7 @@ spec: kind, uid?' type: string type: object + x-kubernetes-map-type: atomic user: description: 'user is the rados user name. Default is admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' @@ -9766,6 +9811,7 @@ spec: kind, uid?' type: string type: object + x-kubernetes-map-type: atomic sslEnabled: description: sslEnabled Flag enable/disable SSL communication with Gateway, default @@ -9898,6 +9944,7 @@ spec: kind, uid?' type: string type: object + x-kubernetes-map-type: atomic volumeName: description: volumeName is the human-readable name of the StorageOS volume. Volume names @@ -11291,9 +11338,3 @@ spec: type: object served: true storage: true -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/schemas/collector-troubleshoot-v1beta2.json b/schemas/collector-troubleshoot-v1beta2.json index f84dd1dc8..ba9ac4d70 100644 --- a/schemas/collector-troubleshoot-v1beta2.json +++ b/schemas/collector-troubleshoot-v1beta2.json @@ -958,7 +958,8 @@ } } } - } + }, + "x-kubernetes-map-type": "atomic" }, "weight": { "description": "Weight associated with matching the corresponding nodeSelectorTerm, in the range 1-100.", @@ -1040,10 +1041,12 @@ } } } - } + }, + "x-kubernetes-map-type": "atomic" } } - } + }, + "x-kubernetes-map-type": "atomic" } } }, @@ -1109,7 +1112,8 @@ "type": "string" } } - } + }, + "x-kubernetes-map-type": "atomic" }, "namespaceSelector": { "description": "A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means \"this pod's namespace\". An empty selector ({}) matches all namespaces.", @@ -1151,7 +1155,8 @@ "type": "string" } } - } + }, + "x-kubernetes-map-type": "atomic" }, "namespaces": { "description": "namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means \"this pod's namespace\".", @@ -1224,7 +1229,8 @@ "type": "string" } } - } + }, + "x-kubernetes-map-type": "atomic" }, "namespaceSelector": { "description": "A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means \"this pod's namespace\". An empty selector ({}) matches all namespaces.", @@ -1266,7 +1272,8 @@ "type": "string" } } - } + }, + "x-kubernetes-map-type": "atomic" }, "namespaces": { "description": "namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means \"this pod's namespace\".", @@ -1346,7 +1353,8 @@ "type": "string" } } - } + }, + "x-kubernetes-map-type": "atomic" }, "namespaceSelector": { "description": "A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means \"this pod's namespace\". An empty selector ({}) matches all namespaces.", @@ -1388,7 +1396,8 @@ "type": "string" } } - } + }, + "x-kubernetes-map-type": "atomic" }, "namespaces": { "description": "namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means \"this pod's namespace\".", @@ -1461,7 +1470,8 @@ "type": "string" } } - } + }, + "x-kubernetes-map-type": "atomic" }, "namespaceSelector": { "description": "A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means \"this pod's namespace\". An empty selector ({}) matches all namespaces.", @@ -1503,7 +1513,8 @@ "type": "string" } } - } + }, + "x-kubernetes-map-type": "atomic" }, "namespaces": { "description": "namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means \"this pod's namespace\".", @@ -1592,7 +1603,8 @@ "description": "Specify whether the ConfigMap or its key must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" }, "fieldRef": { "description": "Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['\u003cKEY\u003e']`, `metadata.annotations['\u003cKEY\u003e']`, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.", @@ -1609,7 +1621,8 @@ "description": "Path of the field to select in the specified API version.", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "resourceFieldRef": { "description": "Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.", @@ -1639,7 +1652,8 @@ "description": "Required: resource to select", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "secretKeyRef": { "description": "Selects a key of a secret in the pod's namespace", @@ -1660,7 +1674,8 @@ "description": "Specify whether the Secret or its key must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" } } } @@ -1686,7 +1701,8 @@ "description": "Specify whether the ConfigMap must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" }, "prefix": { "description": "An optional identifier to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER.", @@ -1704,7 +1720,8 @@ "description": "Specify whether the Secret must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" } } } @@ -2782,7 +2799,8 @@ "description": "Specify whether the ConfigMap or its key must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" }, "fieldRef": { "description": "Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['\u003cKEY\u003e']`, `metadata.annotations['\u003cKEY\u003e']`, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.", @@ -2799,7 +2817,8 @@ "description": "Path of the field to select in the specified API version.", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "resourceFieldRef": { "description": "Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.", @@ -2829,7 +2848,8 @@ "description": "Required: resource to select", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "secretKeyRef": { "description": "Selects a key of a secret in the pod's namespace", @@ -2850,7 +2870,8 @@ "description": "Specify whether the Secret or its key must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" } } } @@ -2876,7 +2897,8 @@ "description": "Specify whether the ConfigMap must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" }, "prefix": { "description": "An optional identifier to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER.", @@ -2894,7 +2916,8 @@ "description": "Specify whether the Secret must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" } } } @@ -3918,7 +3941,8 @@ "description": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" } }, "initContainers": { @@ -3986,7 +4010,8 @@ "description": "Specify whether the ConfigMap or its key must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" }, "fieldRef": { "description": "Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['\u003cKEY\u003e']`, `metadata.annotations['\u003cKEY\u003e']`, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.", @@ -4003,7 +4028,8 @@ "description": "Path of the field to select in the specified API version.", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "resourceFieldRef": { "description": "Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.", @@ -4033,7 +4059,8 @@ "description": "Required: resource to select", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "secretKeyRef": { "description": "Selects a key of a secret in the pod's namespace", @@ -4054,7 +4081,8 @@ "description": "Specify whether the Secret or its key must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" } } } @@ -4080,7 +4108,8 @@ "description": "Specify whether the ConfigMap must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" }, "prefix": { "description": "An optional identifier to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER.", @@ -4098,7 +4127,8 @@ "description": "Specify whether the Secret must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" } } } @@ -5433,7 +5463,8 @@ "type": "string" } } - } + }, + "x-kubernetes-map-type": "atomic" }, "matchLabelKeys": { "description": "MatchLabelKeys is a set of pod label keys to select the pods over which spreading will be calculated. The keys are used to lookup values from the incoming pod labels, those key-value labels are ANDed with labelSelector to select the group of existing pods over which spreading will be calculated for the incoming pod. Keys that don't exist in the incoming pod labels will be ignored. A null or empty list means only match against labelSelector.", @@ -5466,7 +5497,7 @@ "type": "string" }, "whenUnsatisfiable": { - "description": "WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy the spread constraint. - DoNotSchedule (default) tells the scheduler not to schedule it. - ScheduleAnyway tells the scheduler to schedule the pod in any location, but giving higher precedence to topologies that would help reduce the skew. A constraint is considered \"Unsatisfiable\" for an incoming pod if and only if every possible node assignment for that pod would violate \"MaxSkew\" on some topology. For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same labelSelector spread as 3/1/1: | zone1 | zone2 | zone3 | | P P P | P | P | If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler won't make it *more* imbalanced. It's a required field.", + "description": "WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy the spread constraint. - DoNotSchedule (default) tells the scheduler not to schedule it. - ScheduleAnyway tells the scheduler to schedule the pod in any location, but giving higher precedence to topologies that would help reduce the skew. A constraint is considered \"Unsatisfiable\" for an incoming pod if and only if every possible node assignment for that pod would violate \"MaxSkew\" on some topology. For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same labelSelector spread as 3/1/1: | zone1 | zone2 | zone3 | | P P P | P | P | If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler won't make it *more* imbalanced. It's a required field.", "type": "string" } } @@ -5603,7 +5634,8 @@ "description": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "user": { "description": "user is optional: User is the rados user name, default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it", @@ -5634,7 +5666,8 @@ "description": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "volumeID": { "description": "volumeID used to identify the volume in cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md", @@ -5686,7 +5719,8 @@ "description": "optional specify whether the ConfigMap or its keys must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" }, "csi": { "description": "csi (Container Storage Interface) represents ephemeral storage that is handled by certain external CSI drivers (Beta feature).", @@ -5711,7 +5745,8 @@ "description": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "readOnly": { "description": "readOnly specifies a read-only configuration for the volume. Defaults to false (read/write).", @@ -5760,7 +5795,8 @@ "description": "Path of the field to select in the specified API version.", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "mode": { "description": "Optional: mode bits used to set permissions on this file, must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.", @@ -5799,7 +5835,8 @@ "description": "Required: resource to select", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" } } } @@ -5830,7 +5867,7 @@ } }, "ephemeral": { - "description": "ephemeral represents a volume that is handled by a cluster storage driver. The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, and deleted when the pod is removed. \n Use this if: a) the volume is only needed while the pod runs, b) features of normal volumes like restoring from snapshot or capacity tracking are needed, c) the storage driver is specified through a storage class, and d) the storage driver supports dynamic volume provisioning through a PersistentVolumeClaim (see EphemeralVolumeSource for more information on the connection between this volume type and PersistentVolumeClaim). \n Use PersistentVolumeClaim or one of the vendor-specific APIs for volumes that persist for longer than the lifecycle of an individual pod. \n Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to be used that way - see the documentation of the driver for more information. \n A pod can use both types of ephemeral volumes and persistent volumes at the same time.", + "description": "ephemeral represents a volume that is handled by a cluster storage driver. The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, and deleted when the pod is removed. \n Use this if: a) the volume is only needed while the pod runs, b) features of normal volumes like restoring from snapshot or capacity tracking are needed, c) the storage driver is specified through a storage class, and d) the storage driver supports dynamic volume provisioning through a PersistentVolumeClaim (see EphemeralVolumeSource for more information on the connection between this volume type and PersistentVolumeClaim). \n Use PersistentVolumeClaim or one of the vendor-specific APIs for volumes that persist for longer than the lifecycle of an individual pod. \n Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to be used that way - see the documentation of the driver for more information. \n A pod can use both types of ephemeral volumes and persistent volumes at the same time.", "type": "object", "properties": { "volumeClaimTemplate": { @@ -5875,10 +5912,11 @@ "description": "Name is the name of resource being referenced", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "dataSourceRef": { - "description": "dataSourceRef specifies the object from which to populate the volume with data, if a non-empty volume is desired. This may be any object from a non-empty API group (non core object) or a PersistentVolumeClaim object. When this field is specified, volume binding will only succeed if the type of the specified object matches some installed volume populator or dynamic provisioner. This field will replace the functionality of the dataSource field and as such if both fields are non-empty, they must have the same value. For backwards compatibility, when namespace isn't specified in dataSourceRef, both fields (dataSource and dataSourceRef) will be set to the same value automatically if one of them is empty and the other is non-empty. When namespace is specified in dataSourceRef, dataSource isn't set to the same value and must be empty. There are three important differences between dataSource and dataSourceRef: * While dataSource only allows two specific types of objects, dataSourceRef allows any non-core object, as well as PersistentVolumeClaim objects. * While dataSource ignores disallowed values (dropping them), dataSourceRef preserves all values, and generates an error if a disallowed value is specified. * While dataSource only allows local objects, dataSourceRef allows objects in any namespaces. (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled.", + "description": "dataSourceRef specifies the object from which to populate the volume with data, if a non-empty volume is desired. This may be any object from a non-empty API group (non core object) or a PersistentVolumeClaim object. When this field is specified, volume binding will only succeed if the type of the specified object matches some installed volume populator or dynamic provisioner. This field will replace the functionality of the dataSource field and as such if both fields are non-empty, they must have the same value. For backwards compatibility, when namespace isn't specified in dataSourceRef, both fields (dataSource and dataSourceRef) will be set to the same value automatically if one of them is empty and the other is non-empty. When namespace is specified in dataSourceRef, dataSource isn't set to the same value and must be empty. There are three important differences between dataSource and dataSourceRef: * While dataSource only allows two specific types of objects, dataSourceRef allows any non-core object, as well as PersistentVolumeClaim objects. * While dataSource ignores disallowed values (dropping them), dataSourceRef preserves all values, and generates an error if a disallowed value is specified. * While dataSource only allows local objects, dataSourceRef allows objects in any namespaces. (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled.", "type": "object", "required": [ "kind", @@ -6002,7 +6040,8 @@ "type": "string" } } - } + }, + "x-kubernetes-map-type": "atomic" }, "storageClassName": { "description": "storageClassName is the name of the StorageClass required by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1", @@ -6089,7 +6128,8 @@ "description": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" } } }, @@ -6250,7 +6290,8 @@ "description": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "targetPortal": { "description": "targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port is other than default (typically TCP ports 860 and 3260).", @@ -6394,7 +6435,8 @@ "description": "optional specify whether the ConfigMap or its keys must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" }, "downwardAPI": { "description": "downwardAPI information about the downwardAPI data to project", @@ -6425,7 +6467,8 @@ "description": "Path of the field to select in the specified API version.", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "mode": { "description": "Optional: mode bits used to set permissions on this file, must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.", @@ -6464,7 +6507,8 @@ "description": "Required: resource to select", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" } } } @@ -6510,7 +6554,8 @@ "description": "optional field specify whether the Secret or its key must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" }, "serviceAccountToken": { "description": "serviceAccountToken is information about the serviceAccountToken data to project", @@ -6616,7 +6661,8 @@ "description": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "user": { "description": "user is the rados user name. Default is admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it", @@ -6657,7 +6703,8 @@ "description": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "sslEnabled": { "description": "sslEnabled Flag enable/disable SSL communication with Gateway, default false", @@ -6747,7 +6794,8 @@ "description": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "volumeName": { "description": "volumeName is the human-readable name of the StorageOS volume. Volume names are only unique within a namespace.", diff --git a/schemas/preflight-troubleshoot-v1beta2.json b/schemas/preflight-troubleshoot-v1beta2.json index bf254ebee..68aeab4c0 100644 --- a/schemas/preflight-troubleshoot-v1beta2.json +++ b/schemas/preflight-troubleshoot-v1beta2.json @@ -3182,7 +3182,8 @@ } } } - } + }, + "x-kubernetes-map-type": "atomic" }, "weight": { "description": "Weight associated with matching the corresponding nodeSelectorTerm, in the range 1-100.", @@ -3264,10 +3265,12 @@ } } } - } + }, + "x-kubernetes-map-type": "atomic" } } - } + }, + "x-kubernetes-map-type": "atomic" } } }, @@ -3333,7 +3336,8 @@ "type": "string" } } - } + }, + "x-kubernetes-map-type": "atomic" }, "namespaceSelector": { "description": "A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means \"this pod's namespace\". An empty selector ({}) matches all namespaces.", @@ -3375,7 +3379,8 @@ "type": "string" } } - } + }, + "x-kubernetes-map-type": "atomic" }, "namespaces": { "description": "namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means \"this pod's namespace\".", @@ -3448,7 +3453,8 @@ "type": "string" } } - } + }, + "x-kubernetes-map-type": "atomic" }, "namespaceSelector": { "description": "A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means \"this pod's namespace\". An empty selector ({}) matches all namespaces.", @@ -3490,7 +3496,8 @@ "type": "string" } } - } + }, + "x-kubernetes-map-type": "atomic" }, "namespaces": { "description": "namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means \"this pod's namespace\".", @@ -3570,7 +3577,8 @@ "type": "string" } } - } + }, + "x-kubernetes-map-type": "atomic" }, "namespaceSelector": { "description": "A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means \"this pod's namespace\". An empty selector ({}) matches all namespaces.", @@ -3612,7 +3620,8 @@ "type": "string" } } - } + }, + "x-kubernetes-map-type": "atomic" }, "namespaces": { "description": "namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means \"this pod's namespace\".", @@ -3685,7 +3694,8 @@ "type": "string" } } - } + }, + "x-kubernetes-map-type": "atomic" }, "namespaceSelector": { "description": "A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means \"this pod's namespace\". An empty selector ({}) matches all namespaces.", @@ -3727,7 +3737,8 @@ "type": "string" } } - } + }, + "x-kubernetes-map-type": "atomic" }, "namespaces": { "description": "namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means \"this pod's namespace\".", @@ -3816,7 +3827,8 @@ "description": "Specify whether the ConfigMap or its key must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" }, "fieldRef": { "description": "Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['\u003cKEY\u003e']`, `metadata.annotations['\u003cKEY\u003e']`, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.", @@ -3833,7 +3845,8 @@ "description": "Path of the field to select in the specified API version.", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "resourceFieldRef": { "description": "Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.", @@ -3863,7 +3876,8 @@ "description": "Required: resource to select", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "secretKeyRef": { "description": "Selects a key of a secret in the pod's namespace", @@ -3884,7 +3898,8 @@ "description": "Specify whether the Secret or its key must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" } } } @@ -3910,7 +3925,8 @@ "description": "Specify whether the ConfigMap must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" }, "prefix": { "description": "An optional identifier to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER.", @@ -3928,7 +3944,8 @@ "description": "Specify whether the Secret must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" } } } @@ -5006,7 +5023,8 @@ "description": "Specify whether the ConfigMap or its key must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" }, "fieldRef": { "description": "Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['\u003cKEY\u003e']`, `metadata.annotations['\u003cKEY\u003e']`, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.", @@ -5023,7 +5041,8 @@ "description": "Path of the field to select in the specified API version.", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "resourceFieldRef": { "description": "Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.", @@ -5053,7 +5072,8 @@ "description": "Required: resource to select", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "secretKeyRef": { "description": "Selects a key of a secret in the pod's namespace", @@ -5074,7 +5094,8 @@ "description": "Specify whether the Secret or its key must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" } } } @@ -5100,7 +5121,8 @@ "description": "Specify whether the ConfigMap must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" }, "prefix": { "description": "An optional identifier to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER.", @@ -5118,7 +5140,8 @@ "description": "Specify whether the Secret must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" } } } @@ -6142,7 +6165,8 @@ "description": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" } }, "initContainers": { @@ -6210,7 +6234,8 @@ "description": "Specify whether the ConfigMap or its key must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" }, "fieldRef": { "description": "Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['\u003cKEY\u003e']`, `metadata.annotations['\u003cKEY\u003e']`, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.", @@ -6227,7 +6252,8 @@ "description": "Path of the field to select in the specified API version.", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "resourceFieldRef": { "description": "Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.", @@ -6257,7 +6283,8 @@ "description": "Required: resource to select", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "secretKeyRef": { "description": "Selects a key of a secret in the pod's namespace", @@ -6278,7 +6305,8 @@ "description": "Specify whether the Secret or its key must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" } } } @@ -6304,7 +6332,8 @@ "description": "Specify whether the ConfigMap must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" }, "prefix": { "description": "An optional identifier to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER.", @@ -6322,7 +6351,8 @@ "description": "Specify whether the Secret must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" } } } @@ -7657,7 +7687,8 @@ "type": "string" } } - } + }, + "x-kubernetes-map-type": "atomic" }, "matchLabelKeys": { "description": "MatchLabelKeys is a set of pod label keys to select the pods over which spreading will be calculated. The keys are used to lookup values from the incoming pod labels, those key-value labels are ANDed with labelSelector to select the group of existing pods over which spreading will be calculated for the incoming pod. Keys that don't exist in the incoming pod labels will be ignored. A null or empty list means only match against labelSelector.", @@ -7690,7 +7721,7 @@ "type": "string" }, "whenUnsatisfiable": { - "description": "WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy the spread constraint. - DoNotSchedule (default) tells the scheduler not to schedule it. - ScheduleAnyway tells the scheduler to schedule the pod in any location, but giving higher precedence to topologies that would help reduce the skew. A constraint is considered \"Unsatisfiable\" for an incoming pod if and only if every possible node assignment for that pod would violate \"MaxSkew\" on some topology. For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same labelSelector spread as 3/1/1: | zone1 | zone2 | zone3 | | P P P | P | P | If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler won't make it *more* imbalanced. It's a required field.", + "description": "WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy the spread constraint. - DoNotSchedule (default) tells the scheduler not to schedule it. - ScheduleAnyway tells the scheduler to schedule the pod in any location, but giving higher precedence to topologies that would help reduce the skew. A constraint is considered \"Unsatisfiable\" for an incoming pod if and only if every possible node assignment for that pod would violate \"MaxSkew\" on some topology. For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same labelSelector spread as 3/1/1: | zone1 | zone2 | zone3 | | P P P | P | P | If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler won't make it *more* imbalanced. It's a required field.", "type": "string" } } @@ -7827,7 +7858,8 @@ "description": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "user": { "description": "user is optional: User is the rados user name, default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it", @@ -7858,7 +7890,8 @@ "description": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "volumeID": { "description": "volumeID used to identify the volume in cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md", @@ -7910,7 +7943,8 @@ "description": "optional specify whether the ConfigMap or its keys must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" }, "csi": { "description": "csi (Container Storage Interface) represents ephemeral storage that is handled by certain external CSI drivers (Beta feature).", @@ -7935,7 +7969,8 @@ "description": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "readOnly": { "description": "readOnly specifies a read-only configuration for the volume. Defaults to false (read/write).", @@ -7984,7 +8019,8 @@ "description": "Path of the field to select in the specified API version.", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "mode": { "description": "Optional: mode bits used to set permissions on this file, must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.", @@ -8023,7 +8059,8 @@ "description": "Required: resource to select", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" } } } @@ -8054,7 +8091,7 @@ } }, "ephemeral": { - "description": "ephemeral represents a volume that is handled by a cluster storage driver. The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, and deleted when the pod is removed. \n Use this if: a) the volume is only needed while the pod runs, b) features of normal volumes like restoring from snapshot or capacity tracking are needed, c) the storage driver is specified through a storage class, and d) the storage driver supports dynamic volume provisioning through a PersistentVolumeClaim (see EphemeralVolumeSource for more information on the connection between this volume type and PersistentVolumeClaim). \n Use PersistentVolumeClaim or one of the vendor-specific APIs for volumes that persist for longer than the lifecycle of an individual pod. \n Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to be used that way - see the documentation of the driver for more information. \n A pod can use both types of ephemeral volumes and persistent volumes at the same time.", + "description": "ephemeral represents a volume that is handled by a cluster storage driver. The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, and deleted when the pod is removed. \n Use this if: a) the volume is only needed while the pod runs, b) features of normal volumes like restoring from snapshot or capacity tracking are needed, c) the storage driver is specified through a storage class, and d) the storage driver supports dynamic volume provisioning through a PersistentVolumeClaim (see EphemeralVolumeSource for more information on the connection between this volume type and PersistentVolumeClaim). \n Use PersistentVolumeClaim or one of the vendor-specific APIs for volumes that persist for longer than the lifecycle of an individual pod. \n Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to be used that way - see the documentation of the driver for more information. \n A pod can use both types of ephemeral volumes and persistent volumes at the same time.", "type": "object", "properties": { "volumeClaimTemplate": { @@ -8099,10 +8136,11 @@ "description": "Name is the name of resource being referenced", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "dataSourceRef": { - "description": "dataSourceRef specifies the object from which to populate the volume with data, if a non-empty volume is desired. This may be any object from a non-empty API group (non core object) or a PersistentVolumeClaim object. When this field is specified, volume binding will only succeed if the type of the specified object matches some installed volume populator or dynamic provisioner. This field will replace the functionality of the dataSource field and as such if both fields are non-empty, they must have the same value. For backwards compatibility, when namespace isn't specified in dataSourceRef, both fields (dataSource and dataSourceRef) will be set to the same value automatically if one of them is empty and the other is non-empty. When namespace is specified in dataSourceRef, dataSource isn't set to the same value and must be empty. There are three important differences between dataSource and dataSourceRef: * While dataSource only allows two specific types of objects, dataSourceRef allows any non-core object, as well as PersistentVolumeClaim objects. * While dataSource ignores disallowed values (dropping them), dataSourceRef preserves all values, and generates an error if a disallowed value is specified. * While dataSource only allows local objects, dataSourceRef allows objects in any namespaces. (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled.", + "description": "dataSourceRef specifies the object from which to populate the volume with data, if a non-empty volume is desired. This may be any object from a non-empty API group (non core object) or a PersistentVolumeClaim object. When this field is specified, volume binding will only succeed if the type of the specified object matches some installed volume populator or dynamic provisioner. This field will replace the functionality of the dataSource field and as such if both fields are non-empty, they must have the same value. For backwards compatibility, when namespace isn't specified in dataSourceRef, both fields (dataSource and dataSourceRef) will be set to the same value automatically if one of them is empty and the other is non-empty. When namespace is specified in dataSourceRef, dataSource isn't set to the same value and must be empty. There are three important differences between dataSource and dataSourceRef: * While dataSource only allows two specific types of objects, dataSourceRef allows any non-core object, as well as PersistentVolumeClaim objects. * While dataSource ignores disallowed values (dropping them), dataSourceRef preserves all values, and generates an error if a disallowed value is specified. * While dataSource only allows local objects, dataSourceRef allows objects in any namespaces. (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled.", "type": "object", "required": [ "kind", @@ -8226,7 +8264,8 @@ "type": "string" } } - } + }, + "x-kubernetes-map-type": "atomic" }, "storageClassName": { "description": "storageClassName is the name of the StorageClass required by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1", @@ -8313,7 +8352,8 @@ "description": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" } } }, @@ -8474,7 +8514,8 @@ "description": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "targetPortal": { "description": "targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port is other than default (typically TCP ports 860 and 3260).", @@ -8618,7 +8659,8 @@ "description": "optional specify whether the ConfigMap or its keys must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" }, "downwardAPI": { "description": "downwardAPI information about the downwardAPI data to project", @@ -8649,7 +8691,8 @@ "description": "Path of the field to select in the specified API version.", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "mode": { "description": "Optional: mode bits used to set permissions on this file, must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.", @@ -8688,7 +8731,8 @@ "description": "Required: resource to select", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" } } } @@ -8734,7 +8778,8 @@ "description": "optional field specify whether the Secret or its key must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" }, "serviceAccountToken": { "description": "serviceAccountToken is information about the serviceAccountToken data to project", @@ -8840,7 +8885,8 @@ "description": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "user": { "description": "user is the rados user name. Default is admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it", @@ -8881,7 +8927,8 @@ "description": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "sslEnabled": { "description": "sslEnabled Flag enable/disable SSL communication with Gateway, default false", @@ -8971,7 +9018,8 @@ "description": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "volumeName": { "description": "volumeName is the human-readable name of the StorageOS volume. Volume names are only unique within a namespace.", diff --git a/schemas/supportbundle-troubleshoot-v1beta2.json b/schemas/supportbundle-troubleshoot-v1beta2.json index 2de4ec2d4..15b6ed2cb 100644 --- a/schemas/supportbundle-troubleshoot-v1beta2.json +++ b/schemas/supportbundle-troubleshoot-v1beta2.json @@ -3228,7 +3228,8 @@ } } } - } + }, + "x-kubernetes-map-type": "atomic" }, "weight": { "description": "Weight associated with matching the corresponding nodeSelectorTerm, in the range 1-100.", @@ -3310,10 +3311,12 @@ } } } - } + }, + "x-kubernetes-map-type": "atomic" } } - } + }, + "x-kubernetes-map-type": "atomic" } } }, @@ -3379,7 +3382,8 @@ "type": "string" } } - } + }, + "x-kubernetes-map-type": "atomic" }, "namespaceSelector": { "description": "A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means \"this pod's namespace\". An empty selector ({}) matches all namespaces.", @@ -3421,7 +3425,8 @@ "type": "string" } } - } + }, + "x-kubernetes-map-type": "atomic" }, "namespaces": { "description": "namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means \"this pod's namespace\".", @@ -3494,7 +3499,8 @@ "type": "string" } } - } + }, + "x-kubernetes-map-type": "atomic" }, "namespaceSelector": { "description": "A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means \"this pod's namespace\". An empty selector ({}) matches all namespaces.", @@ -3536,7 +3542,8 @@ "type": "string" } } - } + }, + "x-kubernetes-map-type": "atomic" }, "namespaces": { "description": "namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means \"this pod's namespace\".", @@ -3616,7 +3623,8 @@ "type": "string" } } - } + }, + "x-kubernetes-map-type": "atomic" }, "namespaceSelector": { "description": "A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means \"this pod's namespace\". An empty selector ({}) matches all namespaces.", @@ -3658,7 +3666,8 @@ "type": "string" } } - } + }, + "x-kubernetes-map-type": "atomic" }, "namespaces": { "description": "namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means \"this pod's namespace\".", @@ -3731,7 +3740,8 @@ "type": "string" } } - } + }, + "x-kubernetes-map-type": "atomic" }, "namespaceSelector": { "description": "A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means \"this pod's namespace\". An empty selector ({}) matches all namespaces.", @@ -3773,7 +3783,8 @@ "type": "string" } } - } + }, + "x-kubernetes-map-type": "atomic" }, "namespaces": { "description": "namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means \"this pod's namespace\".", @@ -3862,7 +3873,8 @@ "description": "Specify whether the ConfigMap or its key must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" }, "fieldRef": { "description": "Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['\u003cKEY\u003e']`, `metadata.annotations['\u003cKEY\u003e']`, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.", @@ -3879,7 +3891,8 @@ "description": "Path of the field to select in the specified API version.", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "resourceFieldRef": { "description": "Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.", @@ -3909,7 +3922,8 @@ "description": "Required: resource to select", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "secretKeyRef": { "description": "Selects a key of a secret in the pod's namespace", @@ -3930,7 +3944,8 @@ "description": "Specify whether the Secret or its key must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" } } } @@ -3956,7 +3971,8 @@ "description": "Specify whether the ConfigMap must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" }, "prefix": { "description": "An optional identifier to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER.", @@ -3974,7 +3990,8 @@ "description": "Specify whether the Secret must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" } } } @@ -5052,7 +5069,8 @@ "description": "Specify whether the ConfigMap or its key must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" }, "fieldRef": { "description": "Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['\u003cKEY\u003e']`, `metadata.annotations['\u003cKEY\u003e']`, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.", @@ -5069,7 +5087,8 @@ "description": "Path of the field to select in the specified API version.", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "resourceFieldRef": { "description": "Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.", @@ -5099,7 +5118,8 @@ "description": "Required: resource to select", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "secretKeyRef": { "description": "Selects a key of a secret in the pod's namespace", @@ -5120,7 +5140,8 @@ "description": "Specify whether the Secret or its key must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" } } } @@ -5146,7 +5167,8 @@ "description": "Specify whether the ConfigMap must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" }, "prefix": { "description": "An optional identifier to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER.", @@ -5164,7 +5186,8 @@ "description": "Specify whether the Secret must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" } } } @@ -6188,7 +6211,8 @@ "description": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" } }, "initContainers": { @@ -6256,7 +6280,8 @@ "description": "Specify whether the ConfigMap or its key must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" }, "fieldRef": { "description": "Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['\u003cKEY\u003e']`, `metadata.annotations['\u003cKEY\u003e']`, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.", @@ -6273,7 +6298,8 @@ "description": "Path of the field to select in the specified API version.", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "resourceFieldRef": { "description": "Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.", @@ -6303,7 +6329,8 @@ "description": "Required: resource to select", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "secretKeyRef": { "description": "Selects a key of a secret in the pod's namespace", @@ -6324,7 +6351,8 @@ "description": "Specify whether the Secret or its key must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" } } } @@ -6350,7 +6378,8 @@ "description": "Specify whether the ConfigMap must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" }, "prefix": { "description": "An optional identifier to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER.", @@ -6368,7 +6397,8 @@ "description": "Specify whether the Secret must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" } } } @@ -7703,7 +7733,8 @@ "type": "string" } } - } + }, + "x-kubernetes-map-type": "atomic" }, "matchLabelKeys": { "description": "MatchLabelKeys is a set of pod label keys to select the pods over which spreading will be calculated. The keys are used to lookup values from the incoming pod labels, those key-value labels are ANDed with labelSelector to select the group of existing pods over which spreading will be calculated for the incoming pod. Keys that don't exist in the incoming pod labels will be ignored. A null or empty list means only match against labelSelector.", @@ -7736,7 +7767,7 @@ "type": "string" }, "whenUnsatisfiable": { - "description": "WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy the spread constraint. - DoNotSchedule (default) tells the scheduler not to schedule it. - ScheduleAnyway tells the scheduler to schedule the pod in any location, but giving higher precedence to topologies that would help reduce the skew. A constraint is considered \"Unsatisfiable\" for an incoming pod if and only if every possible node assignment for that pod would violate \"MaxSkew\" on some topology. For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same labelSelector spread as 3/1/1: | zone1 | zone2 | zone3 | | P P P | P | P | If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler won't make it *more* imbalanced. It's a required field.", + "description": "WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy the spread constraint. - DoNotSchedule (default) tells the scheduler not to schedule it. - ScheduleAnyway tells the scheduler to schedule the pod in any location, but giving higher precedence to topologies that would help reduce the skew. A constraint is considered \"Unsatisfiable\" for an incoming pod if and only if every possible node assignment for that pod would violate \"MaxSkew\" on some topology. For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same labelSelector spread as 3/1/1: | zone1 | zone2 | zone3 | | P P P | P | P | If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler won't make it *more* imbalanced. It's a required field.", "type": "string" } } @@ -7873,7 +7904,8 @@ "description": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "user": { "description": "user is optional: User is the rados user name, default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it", @@ -7904,7 +7936,8 @@ "description": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "volumeID": { "description": "volumeID used to identify the volume in cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md", @@ -7956,7 +7989,8 @@ "description": "optional specify whether the ConfigMap or its keys must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" }, "csi": { "description": "csi (Container Storage Interface) represents ephemeral storage that is handled by certain external CSI drivers (Beta feature).", @@ -7981,7 +8015,8 @@ "description": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "readOnly": { "description": "readOnly specifies a read-only configuration for the volume. Defaults to false (read/write).", @@ -8030,7 +8065,8 @@ "description": "Path of the field to select in the specified API version.", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "mode": { "description": "Optional: mode bits used to set permissions on this file, must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.", @@ -8069,7 +8105,8 @@ "description": "Required: resource to select", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" } } } @@ -8100,7 +8137,7 @@ } }, "ephemeral": { - "description": "ephemeral represents a volume that is handled by a cluster storage driver. The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, and deleted when the pod is removed. \n Use this if: a) the volume is only needed while the pod runs, b) features of normal volumes like restoring from snapshot or capacity tracking are needed, c) the storage driver is specified through a storage class, and d) the storage driver supports dynamic volume provisioning through a PersistentVolumeClaim (see EphemeralVolumeSource for more information on the connection between this volume type and PersistentVolumeClaim). \n Use PersistentVolumeClaim or one of the vendor-specific APIs for volumes that persist for longer than the lifecycle of an individual pod. \n Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to be used that way - see the documentation of the driver for more information. \n A pod can use both types of ephemeral volumes and persistent volumes at the same time.", + "description": "ephemeral represents a volume that is handled by a cluster storage driver. The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, and deleted when the pod is removed. \n Use this if: a) the volume is only needed while the pod runs, b) features of normal volumes like restoring from snapshot or capacity tracking are needed, c) the storage driver is specified through a storage class, and d) the storage driver supports dynamic volume provisioning through a PersistentVolumeClaim (see EphemeralVolumeSource for more information on the connection between this volume type and PersistentVolumeClaim). \n Use PersistentVolumeClaim or one of the vendor-specific APIs for volumes that persist for longer than the lifecycle of an individual pod. \n Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to be used that way - see the documentation of the driver for more information. \n A pod can use both types of ephemeral volumes and persistent volumes at the same time.", "type": "object", "properties": { "volumeClaimTemplate": { @@ -8145,10 +8182,11 @@ "description": "Name is the name of resource being referenced", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "dataSourceRef": { - "description": "dataSourceRef specifies the object from which to populate the volume with data, if a non-empty volume is desired. This may be any object from a non-empty API group (non core object) or a PersistentVolumeClaim object. When this field is specified, volume binding will only succeed if the type of the specified object matches some installed volume populator or dynamic provisioner. This field will replace the functionality of the dataSource field and as such if both fields are non-empty, they must have the same value. For backwards compatibility, when namespace isn't specified in dataSourceRef, both fields (dataSource and dataSourceRef) will be set to the same value automatically if one of them is empty and the other is non-empty. When namespace is specified in dataSourceRef, dataSource isn't set to the same value and must be empty. There are three important differences between dataSource and dataSourceRef: * While dataSource only allows two specific types of objects, dataSourceRef allows any non-core object, as well as PersistentVolumeClaim objects. * While dataSource ignores disallowed values (dropping them), dataSourceRef preserves all values, and generates an error if a disallowed value is specified. * While dataSource only allows local objects, dataSourceRef allows objects in any namespaces. (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled.", + "description": "dataSourceRef specifies the object from which to populate the volume with data, if a non-empty volume is desired. This may be any object from a non-empty API group (non core object) or a PersistentVolumeClaim object. When this field is specified, volume binding will only succeed if the type of the specified object matches some installed volume populator or dynamic provisioner. This field will replace the functionality of the dataSource field and as such if both fields are non-empty, they must have the same value. For backwards compatibility, when namespace isn't specified in dataSourceRef, both fields (dataSource and dataSourceRef) will be set to the same value automatically if one of them is empty and the other is non-empty. When namespace is specified in dataSourceRef, dataSource isn't set to the same value and must be empty. There are three important differences between dataSource and dataSourceRef: * While dataSource only allows two specific types of objects, dataSourceRef allows any non-core object, as well as PersistentVolumeClaim objects. * While dataSource ignores disallowed values (dropping them), dataSourceRef preserves all values, and generates an error if a disallowed value is specified. * While dataSource only allows local objects, dataSourceRef allows objects in any namespaces. (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled.", "type": "object", "required": [ "kind", @@ -8272,7 +8310,8 @@ "type": "string" } } - } + }, + "x-kubernetes-map-type": "atomic" }, "storageClassName": { "description": "storageClassName is the name of the StorageClass required by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1", @@ -8359,7 +8398,8 @@ "description": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" } } }, @@ -8520,7 +8560,8 @@ "description": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "targetPortal": { "description": "targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port is other than default (typically TCP ports 860 and 3260).", @@ -8664,7 +8705,8 @@ "description": "optional specify whether the ConfigMap or its keys must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" }, "downwardAPI": { "description": "downwardAPI information about the downwardAPI data to project", @@ -8695,7 +8737,8 @@ "description": "Path of the field to select in the specified API version.", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "mode": { "description": "Optional: mode bits used to set permissions on this file, must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.", @@ -8734,7 +8777,8 @@ "description": "Required: resource to select", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" } } } @@ -8780,7 +8824,8 @@ "description": "optional field specify whether the Secret or its key must be defined", "type": "boolean" } - } + }, + "x-kubernetes-map-type": "atomic" }, "serviceAccountToken": { "description": "serviceAccountToken is information about the serviceAccountToken data to project", @@ -8886,7 +8931,8 @@ "description": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "user": { "description": "user is the rados user name. Default is admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it", @@ -8927,7 +8973,8 @@ "description": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "sslEnabled": { "description": "sslEnabled Flag enable/disable SSL communication with Gateway, default false", @@ -9017,7 +9064,8 @@ "description": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?", "type": "string" } - } + }, + "x-kubernetes-map-type": "atomic" }, "volumeName": { "description": "volumeName is the human-readable name of the StorageOS volume. Volume names are only unique within a namespace.", From 11cf3e9925e99f000dfdf5e6d705f3ca12306757 Mon Sep 17 00:00:00 2001 From: Diamon Wiggins <38189728+diamonwiggins@users.noreply.github.com> Date: Wed, 1 Feb 2023 14:14:43 -0500 Subject: [PATCH 18/55] 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 --- cmd/troubleshoot/cli/run.go | 2 +- pkg/collect/collect.go | 28 ------------ pkg/collect/collector.go | 52 ++++++++++++++++++++++ pkg/collect/collector_test.go | 81 +++++++++++++++++++++++++++++++++++ pkg/preflight/collect.go | 1 + pkg/supportbundle/collect.go | 1 + 6 files changed, 136 insertions(+), 29 deletions(-) diff --git a/cmd/troubleshoot/cli/run.go b/cmd/troubleshoot/cli/run.go index e5ecce6a3..a900f34e8 100644 --- a/cmd/troubleshoot/cli/run.go +++ b/cmd/troubleshoot/cli/run.go @@ -328,7 +328,7 @@ the %s Admin Console to begin analysis.` return nil } - fmt.Printf("%s\n", response.ArchivePath) + fmt.Printf("\n%s\n", response.ArchivePath) return nil } diff --git a/pkg/collect/collect.go b/pkg/collect/collect.go index f30c6cd5d..9cfdd4e15 100644 --- a/pkg/collect/collect.go +++ b/pkg/collect/collect.go @@ -190,31 +190,3 @@ func CollectRemote(c *troubleshootv1beta2.RemoteCollector, additionalRedactors * collectResult.AllCollectedData = allCollectedData return collectResult, nil } - -// Ensure that the specified collector is in the list of collectors -func EnsureCollectorInList(list []*troubleshootv1beta2.Collect, collector troubleshootv1beta2.Collect) []*troubleshootv1beta2.Collect { - for _, inList := range list { - if collector.ClusterResources != nil && inList.ClusterResources != nil { - return list - } - if collector.ClusterInfo != nil && inList.ClusterInfo != nil { - return list - } - } - - return append(list, &collector) -} - -// collect ClusterResources earliest in the list so the pod list does not include pods started by collectors -func EnsureClusterResourcesFirst(list []*troubleshootv1beta2.Collect) []*troubleshootv1beta2.Collect { - sliceOfClusterResources := []*troubleshootv1beta2.Collect{} - sliceOfOtherCollectors := []*troubleshootv1beta2.Collect{} - for _, collector := range list { - if collector.ClusterResources != nil { - sliceOfClusterResources = append(sliceOfClusterResources, []*troubleshootv1beta2.Collect{collector}...) - } else { - sliceOfOtherCollectors = append(sliceOfOtherCollectors, []*troubleshootv1beta2.Collect{collector}...) - } - } - return append(sliceOfClusterResources, sliceOfOtherCollectors...) -} diff --git a/pkg/collect/collector.go b/pkg/collect/collector.go index 4104f5705..96bbf718c 100644 --- a/pkg/collect/collector.go +++ b/pkg/collect/collector.go @@ -2,6 +2,7 @@ package collect import ( "context" + "encoding/json" "fmt" "strconv" "strings" @@ -194,3 +195,54 @@ func getCollectorName(c interface{}) string { } return collector } + +// Ensure that the specified collector is in the list of collectors +func EnsureCollectorInList(list []*troubleshootv1beta2.Collect, collector troubleshootv1beta2.Collect) []*troubleshootv1beta2.Collect { + for _, inList := range list { + if collector.ClusterResources != nil && inList.ClusterResources != nil { + return list + } + if collector.ClusterInfo != nil && inList.ClusterInfo != nil { + return list + } + } + + return append(list, &collector) +} + +// collect ClusterResources earliest in the list so the pod list does not include pods started by collectors +func EnsureClusterResourcesFirst(list []*troubleshootv1beta2.Collect) []*troubleshootv1beta2.Collect { + sliceOfClusterResources := []*troubleshootv1beta2.Collect{} + sliceOfOtherCollectors := []*troubleshootv1beta2.Collect{} + for _, collector := range list { + if collector.ClusterResources != nil { + sliceOfClusterResources = append(sliceOfClusterResources, []*troubleshootv1beta2.Collect{collector}...) + } else { + sliceOfOtherCollectors = append(sliceOfOtherCollectors, []*troubleshootv1beta2.Collect{collector}...) + } + } + return append(sliceOfClusterResources, sliceOfOtherCollectors...) +} + +// deduplicates a list of troubleshootv1beta2.Collect objects +// marshals object to json and then uses its string value to check for uniqueness +// there is no sorting of the keys in the collect object's spec so if the spec isn't an exact match line for line as written, no dedup will occur +func DedupCollectors(allCollectors []*troubleshootv1beta2.Collect) []*troubleshootv1beta2.Collect { + uniqueCollectors := make(map[string]bool) + finalCollectors := []*troubleshootv1beta2.Collect{} + + for _, collector := range allCollectors { + data, err := json.Marshal(collector) + if err != nil { + // return collector as is if for whatever reason it can't be marshalled into json + finalCollectors = append(finalCollectors, collector) + } else { + stringData := string(data) + if _, value := uniqueCollectors[stringData]; !value { + uniqueCollectors[stringData] = true + finalCollectors = append(finalCollectors, collector) + } + } + } + return finalCollectors +} diff --git a/pkg/collect/collector_test.go b/pkg/collect/collector_test.go index 64d3a7640..eb3f33fb1 100644 --- a/pkg/collect/collector_test.go +++ b/pkg/collect/collector_test.go @@ -5,6 +5,7 @@ import ( troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" "github.com/replicatedhq/troubleshoot/pkg/multitype" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -364,3 +365,83 @@ pwd=somethinggoeshere;`, }) } } + +func TestCollector_DedupCollectors(t *testing.T) { + tests := []struct { + name string + Collectors []*troubleshootv1beta2.Collect + want []*troubleshootv1beta2.Collect + }{ + { + name: "multiple cluster info", + Collectors: []*troubleshootv1beta2.Collect{ + { + ClusterInfo: &troubleshootv1beta2.ClusterInfo{}, + }, + { + ClusterInfo: &troubleshootv1beta2.ClusterInfo{}, + }, + }, + want: []*troubleshootv1beta2.Collect{ + { + ClusterInfo: &troubleshootv1beta2.ClusterInfo{}, + }, + }, + }, + { + name: "multiple cluster resources with matching namespace lists", + Collectors: []*troubleshootv1beta2.Collect{ + { + ClusterResources: &troubleshootv1beta2.ClusterResources{ + Namespaces: []string{"namespace1", "namespace2"}, + }, + }, + { + ClusterResources: &troubleshootv1beta2.ClusterResources{ + Namespaces: []string{"namespace1", "namespace2"}, + }, + }, + }, + want: []*troubleshootv1beta2.Collect{ + { + ClusterResources: &troubleshootv1beta2.ClusterResources{ + Namespaces: []string{"namespace1", "namespace2"}, + }, + }, + }, + }, + { + name: "multiple cluster resources with unnique namespace lists", + Collectors: []*troubleshootv1beta2.Collect{ + { + ClusterResources: &troubleshootv1beta2.ClusterResources{ + Namespaces: []string{"namespace1", "namespace2"}, + }, + }, + { + ClusterResources: &troubleshootv1beta2.ClusterResources{ + Namespaces: []string{"namespace1000", "namespace2000"}, + }, + }, + }, + want: []*troubleshootv1beta2.Collect{ + { + ClusterResources: &troubleshootv1beta2.ClusterResources{ + Namespaces: []string{"namespace1", "namespace2"}, + }, + }, + { + ClusterResources: &troubleshootv1beta2.ClusterResources{ + Namespaces: []string{"namespace1000", "namespace2000"}, + }, + }, + }, + }, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + got := DedupCollectors(tc.Collectors) + assert.Equal(t, tc.want, got) + }) + } +} diff --git a/pkg/preflight/collect.go b/pkg/preflight/collect.go index 73382218e..7cf174d88 100644 --- a/pkg/preflight/collect.go +++ b/pkg/preflight/collect.go @@ -135,6 +135,7 @@ func Collect(opts CollectOpts, p *troubleshootv1beta2.Preflight) (CollectResult, } collectSpecs = collect.EnsureCollectorInList(collectSpecs, troubleshootv1beta2.Collect{ClusterInfo: &troubleshootv1beta2.ClusterInfo{}}) collectSpecs = collect.EnsureCollectorInList(collectSpecs, troubleshootv1beta2.Collect{ClusterResources: &troubleshootv1beta2.ClusterResources{}}) + collectSpecs = collect.DedupCollectors(collectSpecs) collectSpecs = collect.EnsureClusterResourcesFirst(collectSpecs) opts.KubernetesRestConfig.QPS = constants.DEFAULT_CLIENT_QPS diff --git a/pkg/supportbundle/collect.go b/pkg/supportbundle/collect.go index cb81b453d..63c0adcc7 100644 --- a/pkg/supportbundle/collect.go +++ b/pkg/supportbundle/collect.go @@ -76,6 +76,7 @@ func runCollectors(collectors []*troubleshootv1beta2.Collect, additionalRedactor collectSpecs = append(collectSpecs, collectors...) collectSpecs = collect.EnsureCollectorInList(collectSpecs, troubleshootv1beta2.Collect{ClusterInfo: &troubleshootv1beta2.ClusterInfo{}}) collectSpecs = collect.EnsureCollectorInList(collectSpecs, troubleshootv1beta2.Collect{ClusterResources: &troubleshootv1beta2.ClusterResources{}}) + collectSpecs = collect.DedupCollectors(collectSpecs) collectSpecs = collect.EnsureClusterResourcesFirst(collectSpecs) opts.KubernetesRestConfig.QPS = constants.DEFAULT_CLIENT_QPS From 4680cd8e1abe67bf9d04c5782a1bfc3b5c0e70e3 Mon Sep 17 00:00:00 2001 From: "yunju.lly" Date: Fri, 3 Feb 2023 19:05:11 +0800 Subject: [PATCH 19/55] 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 --- cmd/troubleshoot/cli/run.go | 8 ++------ pkg/supportbundle/supportbundle.go | 22 ++++++++++++++------- pkg/supportbundle/supportbundle_test.go | 26 +++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 13 deletions(-) diff --git a/cmd/troubleshoot/cli/run.go b/cmd/troubleshoot/cli/run.go index a900f34e8..8385efba0 100644 --- a/cmd/troubleshoot/cli/run.go +++ b/cmd/troubleshoot/cli/run.go @@ -82,7 +82,7 @@ func runTroubleshoot(v *viper.Viper, arg []string) error { // Defining `v` below will render using `v` in reference to Viper unusable. // Therefore refactoring `v` to `val` will make sure we can still use it. - for i, val := range arg { + for _, val := range arg { collectorContent, err := supportbundle.LoadSupportBundleSpec(val) if err != nil { @@ -98,11 +98,7 @@ func runTroubleshoot(v *viper.Viper, arg []string) error { return errors.Wrap(err, "failed to parse support bundle spec") } - if i == 0 { - mainBundle = supportBundle - } else { - mainBundle = supportbundle.ConcatSpec(mainBundle, supportBundle) - } + mainBundle = supportbundle.ConcatSpec(mainBundle, supportBundle) parsedRedactors, err := supportbundle.ParseRedactorsFromDocs(multidocs) if err != nil { diff --git a/pkg/supportbundle/supportbundle.go b/pkg/supportbundle/supportbundle.go index 8061fe408..8cbe1dfc6 100644 --- a/pkg/supportbundle/supportbundle.go +++ b/pkg/supportbundle/supportbundle.go @@ -233,13 +233,21 @@ func AnalyzeSupportBundle(spec *troubleshootv1beta2.SupportBundleSpec, tmpDir st return analyzeResults, nil } -// the intention with these appends is to swap them out at a later date with more specific handlers for merging the spec fields +// ConcatSpec the intention with these appends is to swap them out at a later date with more specific handlers for merging the spec fields func ConcatSpec(target *troubleshootv1beta2.SupportBundle, source *troubleshootv1beta2.SupportBundle) *troubleshootv1beta2.SupportBundle { - newBundle := target.DeepCopy() - newBundle.Spec.Collectors = append(target.Spec.Collectors, source.Spec.Collectors...) - newBundle.Spec.AfterCollection = append(target.Spec.AfterCollection, source.Spec.AfterCollection...) - newBundle.Spec.HostCollectors = append(target.Spec.HostCollectors, source.Spec.HostCollectors...) - newBundle.Spec.HostAnalyzers = append(target.Spec.HostAnalyzers, source.Spec.HostAnalyzers...) - newBundle.Spec.Analyzers = append(target.Spec.Analyzers, source.Spec.Analyzers...) + if source == nil { + return target + } + var newBundle *troubleshootv1beta2.SupportBundle + if target == nil { + newBundle = source + } else { + newBundle = target.DeepCopy() + newBundle.Spec.Collectors = append(target.Spec.Collectors, source.Spec.Collectors...) + newBundle.Spec.AfterCollection = append(target.Spec.AfterCollection, source.Spec.AfterCollection...) + newBundle.Spec.HostCollectors = append(target.Spec.HostCollectors, source.Spec.HostCollectors...) + newBundle.Spec.HostAnalyzers = append(target.Spec.HostAnalyzers, source.Spec.HostAnalyzers...) + newBundle.Spec.Analyzers = append(target.Spec.Analyzers, source.Spec.Analyzers...) + } return newBundle } diff --git a/pkg/supportbundle/supportbundle_test.go b/pkg/supportbundle/supportbundle_test.go index d29891ac2..e99abf9ea 100644 --- a/pkg/supportbundle/supportbundle_test.go +++ b/pkg/supportbundle/supportbundle_test.go @@ -3,6 +3,8 @@ package supportbundle import ( "reflect" "testing" + + troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" ) func Test_LoadAndConcatSpec(t *testing.T) { @@ -44,3 +46,27 @@ func Test_LoadAndConcatSpec(t *testing.T) { } } + +func Test_LoadAndConcatSpec_WithNil(t *testing.T) { + var bundle *troubleshootv1beta2.SupportBundle + // both function arguments are nil + bundle4 := ConcatSpec(bundle, bundle) + if reflect.DeepEqual(bundle4, (*troubleshootv1beta2.SupportBundle)(nil)) == false { + t.Error("concatenating nil pointer with nil pointer has error.") + } + + fulldoc, _ := LoadSupportBundleSpec("test/completebundle.yaml") + bundle, _ = ParseSupportBundleFromDoc(fulldoc) + + // targetBundle is nil pointer + bundle5 := ConcatSpec((*troubleshootv1beta2.SupportBundle)(nil), bundle) + if reflect.DeepEqual(bundle5, bundle) == false { + t.Error("concatenating targetBundle of nil pointer has error.") + } + + // sourceBundle is nil pointer + bundle6 := ConcatSpec(bundle, (*troubleshootv1beta2.SupportBundle)(nil)) + if reflect.DeepEqual(bundle6, bundle) == false { + t.Error("concatenating sourceBundle of nil pointer has error.") + } +} From 6a0807b97fe6bc778b08464fe33828ae9fdb77d3 Mon Sep 17 00:00:00 2001 From: Chase Hainey Date: Mon, 20 Mar 2023 12:38:12 -0600 Subject: [PATCH 20/55] 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 --- pkg/analyze/analyzer.go | 127 ++++++++++++++++---------- pkg/analyze/analyzer_test.go | 6 ++ pkg/analyze/ceph.go | 37 ++++++-- pkg/analyze/ceph_test.go | 6 +- pkg/analyze/cluster_pod_statuses.go | 27 ++++++ pkg/analyze/cluster_version.go | 36 ++++++-- pkg/analyze/configmap.go | 35 +++++-- pkg/analyze/configmap_test.go | 7 +- pkg/analyze/container_runtime.go | 34 +++++-- pkg/analyze/container_runtime_test.go | 6 +- pkg/analyze/crd.go | 37 ++++++-- pkg/analyze/deployment_status.go | 38 ++++++++ pkg/analyze/distribution.go | 34 +++++-- pkg/analyze/image_pull_secret.go | 34 +++++-- pkg/analyze/ingress.go | 35 +++++-- pkg/analyze/job_status.go | 38 ++++++++ pkg/analyze/json_compare.go | 37 ++++++-- pkg/analyze/json_compare_test.go | 6 +- pkg/analyze/kube_resource.go | 36 ++++++-- pkg/analyze/longhorn.go | 23 +++++ pkg/analyze/mysql.go | 45 ++++++--- pkg/analyze/node_resources.go | 35 +++++-- pkg/analyze/node_resources_test.go | 6 +- pkg/analyze/postgres.go | 43 +++++++-- pkg/analyze/redis.go | 43 +++++++-- pkg/analyze/registry.go | 43 +++++++-- pkg/analyze/replicaset_status.go | 38 ++++++++ pkg/analyze/secret.go | 35 +++++-- pkg/analyze/secret_test.go | 5 +- pkg/analyze/statefulset_status.go | 38 ++++++++ pkg/analyze/storage_class.go | 45 ++++++--- pkg/analyze/sysctl.go | 28 +++++- pkg/analyze/sysctl_test.go | 6 +- pkg/analyze/text_analyze.go | 43 +++++++-- pkg/analyze/text_analyze_test.go | 6 +- pkg/analyze/weave.go | 23 +++++ pkg/analyze/yaml_compare.go | 37 ++++++-- pkg/analyze/yaml_compare_test.go | 6 +- pkg/constants/constants.go | 2 +- 39 files changed, 955 insertions(+), 211 deletions(-) diff --git a/pkg/analyze/analyzer.go b/pkg/analyze/analyzer.go index 96730dabf..63521ec8b 100644 --- a/pkg/analyze/analyzer.go +++ b/pkg/analyze/analyzer.go @@ -479,60 +479,24 @@ func Analyze(analyzer *troubleshootv1beta2.Analyze, getFile getCollectedFileCont return results, nil } - if analyzer.RegistryImages != nil { - isExcluded, err := isExcluded(analyzer.RegistryImages.Exclude) - if err != nil { - return nil, err - } - if isExcluded { - return nil, nil - } - result, err := analyzeRegistry(analyzer.RegistryImages, getFile) - if err != nil { - return nil, err - } - result.Strict = analyzer.RegistryImages.Strict.BoolOrDefaultFalse() - return []*AnalyzeResult{result}, nil + isExcluded, err := analyzerInst.IsExcluded() + if err != nil { + return nil, err + } + if isExcluded { + return nil, nil } - if analyzer.WeaveReport != nil { - isExcluded, err := isExcluded(analyzer.WeaveReport.Exclude) - if err != nil { - return nil, err - } - if isExcluded { - return nil, nil - } - results, err := analyzeWeaveReport(analyzer.WeaveReport, findFiles) - if err != nil { - return nil, err - } - for i := range results { - results[i].Strict = analyzer.WeaveReport.Strict.BoolOrDefaultFalse() - } - return results, nil + results, err := analyzerInst.Analyze(getFile, findFiles) + if err != nil { + return nil, err } - if analyzer.Sysctl != nil { - isExcluded, err := isExcluded(analyzer.Sysctl.Exclude) - if err != nil { - return nil, err - } - if isExcluded { - return nil, nil - } - result, err := analyzeSysctl(analyzer.Sysctl, findFiles) - if err != nil { - return nil, err - } - if result == nil { - return []*AnalyzeResult{}, nil - } - result.Strict = analyzer.Sysctl.Strict.BoolOrDefaultFalse() - return []*AnalyzeResult{result}, nil + if results == nil { + results = []*AnalyzeResult{} } - return nil, errors.New("invalid analyzer") + return results, nil } func GetExcludeFlag(analyzer *troubleshootv1beta2.Analyze) *multitype.BoolOrString { @@ -556,3 +520,70 @@ func GetExcludeFlag(analyzer *troubleshootv1beta2.Analyze) *multitype.BoolOrStri return nil } + +type Analyzer interface { + Title() string + IsExcluded() (bool, error) + Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) +} + +func getAnalyzer(analyzer *troubleshootv1beta2.Analyze) Analyzer { + switch { + case analyzer.ClusterVersion != nil: + return &AnalyzeClusterVersion{analyzer: analyzer.ClusterVersion} + case analyzer.StorageClass != nil: + return &AnalyzeStorageClass{analyzer: analyzer.StorageClass} + case analyzer.CustomResourceDefinition != nil: + return &AnalyzeCustomResourceDefinition{analyzer: analyzer.CustomResourceDefinition} + case analyzer.Ingress != nil: + return &AnalyzeIngress{analyzer: analyzer.Ingress} + case analyzer.Secret != nil: + return &AnalyzeSecret{analyzer: analyzer.Secret} + case analyzer.ConfigMap != nil: + return &AnalyzeConfigMap{analyzer: analyzer.ConfigMap} + case analyzer.ImagePullSecret != nil: + return &AnalyzeImagePullSecret{analyzer: analyzer.ImagePullSecret} + case analyzer.DeploymentStatus != nil: + return &AnalyzeDeploymentStatus{analyzer: analyzer.DeploymentStatus} + case analyzer.StatefulsetStatus != nil: + return &AnalyzeStatefulsetStatus{analyzer: analyzer.StatefulsetStatus} + case analyzer.JobStatus != nil: + return &AnalyzeJobStatus{analyzer: analyzer.JobStatus} + case analyzer.ReplicaSetStatus != nil: + return &AnalyzeReplicaSetStatus{analyzer: analyzer.ReplicaSetStatus} + case analyzer.ClusterPodStatuses != nil: + return &AnalyzeClusterPodStatuses{analyzer: analyzer.ClusterPodStatuses} + case analyzer.ContainerRuntime != nil: + return &AnalyzeContainerRuntime{analyzer: analyzer.ContainerRuntime} + case analyzer.Distribution != nil: + return &AnalyzeDistribution{analyzer: analyzer.Distribution} + case analyzer.NodeResources != nil: + return &AnalyzeNodeResources{analyzer: analyzer.NodeResources} + case analyzer.TextAnalyze != nil: + return &AnalyzeTextAnalyze{analyzer: analyzer.TextAnalyze} + case analyzer.YamlCompare != nil: + return &AnalyzeYamlCompare{analyzer: analyzer.YamlCompare} + case analyzer.JsonCompare != nil: + return &AnalyzeJsonCompare{analyzer: analyzer.JsonCompare} + case analyzer.Postgres != nil: + return &AnalyzePostgres{analyzer: analyzer.Postgres} + case analyzer.Mysql != nil: + return &AnalyzeMysql{analyzer: analyzer.Mysql} + case analyzer.Redis != nil: + return &AnalyzeRedis{analyzer: analyzer.Redis} + case analyzer.CephStatus != nil: + return &AnalyzeCephStatus{analyzer: analyzer.CephStatus} + case analyzer.Longhorn != nil: + return &AnalyzeLonghorn{analyzer: analyzer.Longhorn} + case analyzer.RegistryImages != nil: + return &AnalyzeRegistryImages{analyzer: analyzer.RegistryImages} + case analyzer.WeaveReport != nil: + return &AnalyzeWeaveReport{analyzer: analyzer.WeaveReport} + case analyzer.Sysctl != nil: + return &AnalyzeSysctl{analyzer: analyzer.Sysctl} + case analyzer.ClusterResource != nil: + return &AnalyzeClusterResource{analyzer: analyzer.ClusterResource} + default: + return nil + } +} diff --git a/pkg/analyze/analyzer_test.go b/pkg/analyze/analyzer_test.go index 13e7c47c3..0b8b4ad97 100644 --- a/pkg/analyze/analyzer_test.go +++ b/pkg/analyze/analyzer_test.go @@ -65,3 +65,9 @@ func Test_GetExcludeFlag(t *testing.T) { }) } } + +func TestAnalyzeWithNilAnalyzer(t *testing.T) { + got, err := Analyze(nil, nil, nil) + assert.Error(t, err) + assert.Nil(t, got) +} diff --git a/pkg/analyze/ceph.go b/pkg/analyze/ceph.go index d055e4a5b..0b9fb87f6 100644 --- a/pkg/analyze/ceph.go +++ b/pkg/analyze/ceph.go @@ -100,7 +100,35 @@ type PgMap struct { TotalBytes uint64 `json:"bytes_total"` } -func cephStatus(analyzer *troubleshootv1beta2.CephStatusAnalyze, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { +type AnalyzeCephStatus struct { + analyzer *troubleshootv1beta2.CephStatusAnalyze +} + +func (a *AnalyzeCephStatus) Title() string { + title := a.analyzer.CheckName + if title == "" { + title = "Ceph Status" + } + + return title +} + +func (a *AnalyzeCephStatus) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeCephStatus) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + result, err := a.cephStatus(a.analyzer, getFile) + if err != nil { + return nil, err + } + if result != nil { + result.Strict = a.analyzer.Strict.BoolOrDefaultFalse() + } + return []*AnalyzeResult{result}, nil +} + +func (a *AnalyzeCephStatus) cephStatus(analyzer *troubleshootv1beta2.CephStatusAnalyze, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { fileName := path.Join(collect.GetCephCollectorFilepath(analyzer.CollectorName, analyzer.Namespace), "status.json") collected, err := getCollectedFileContents(fileName) @@ -111,13 +139,8 @@ func cephStatus(analyzer *troubleshootv1beta2.CephStatusAnalyze, getCollectedFil return nil, errors.Wrap(err, "failed to read collected ceph status") } - title := analyzer.CheckName - if title == "" { - title = "Ceph Status" - } - analyzeResult := &AnalyzeResult{ - Title: title, + Title: a.Title(), IconKey: "rook", // maybe this should be ceph? IconURI: "https://troubleshoot.sh/images/analyzer-icons/rook.svg?w=11&h=16", } diff --git a/pkg/analyze/ceph_test.go b/pkg/analyze/ceph_test.go index 6ec315423..77319b475 100644 --- a/pkg/analyze/ceph_test.go +++ b/pkg/analyze/ceph_test.go @@ -273,7 +273,11 @@ func Test_cephStatus(t *testing.T) { } } - actual, err := cephStatus(&test.analyzer, test.getFile) + a := AnalyzeCephStatus{ + analyzer: &test.analyzer, + } + + actual, err := a.cephStatus(&test.analyzer, test.getFile) req.NoError(err) assert.Equal(t, test.expectResult, actual) diff --git a/pkg/analyze/cluster_pod_statuses.go b/pkg/analyze/cluster_pod_statuses.go index e643ba742..1cae2d342 100644 --- a/pkg/analyze/cluster_pod_statuses.go +++ b/pkg/analyze/cluster_pod_statuses.go @@ -15,6 +15,33 @@ import ( corev1 "k8s.io/api/core/v1" ) +type AnalyzeClusterPodStatuses struct { + analyzer *troubleshootv1beta2.ClusterPodStatuses +} + +func (a *AnalyzeClusterPodStatuses) Title() string { + if a.analyzer.CheckName != "" { + return a.analyzer.CheckName + } + + return "Cluster Pod Status" +} + +func (a *AnalyzeClusterPodStatuses) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeClusterPodStatuses) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + results, err := clusterPodStatuses(a.analyzer, findFiles) + if err != nil { + return nil, err + } + for i := range results { + results[i].Strict = a.analyzer.Strict.BoolOrDefaultFalse() + } + return results, nil +} + func clusterPodStatuses(analyzer *troubleshootv1beta2.ClusterPodStatuses, getChildCollectedFileContents getChildCollectedFileContents) ([]*AnalyzeResult, error) { excludeFiles := []string{} collected, err := getChildCollectedFileContents(filepath.Join(constants.CLUSTER_RESOURCES_DIR, constants.CLUSTER_RESOURCES_PODS, "*.json"), excludeFiles) diff --git a/pkg/analyze/cluster_version.go b/pkg/analyze/cluster_version.go index 988c7e312..de9790579 100644 --- a/pkg/analyze/cluster_version.go +++ b/pkg/analyze/cluster_version.go @@ -10,6 +10,27 @@ import ( "github.com/replicatedhq/troubleshoot/pkg/collect" ) +type AnalyzeClusterVersion struct { + analyzer *troubleshootv1beta2.ClusterVersion +} + +func (a *AnalyzeClusterVersion) Title() string { + return title(a.analyzer.CheckName) +} + +func (a *AnalyzeClusterVersion) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeClusterVersion) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + result, err := analyzeClusterVersion(a.analyzer, getFile) + if err != nil { + return nil, err + } + result.Strict = a.analyzer.Strict.BoolOrDefaultFalse() + return []*AnalyzeResult{result}, nil +} + func analyzeClusterVersion(analyzer *troubleshootv1beta2.ClusterVersion, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { clusterInfo, err := getCollectedFileContents("cluster-info/cluster_version.json") if err != nil { @@ -29,19 +50,22 @@ func analyzeClusterVersion(analyzer *troubleshootv1beta2.ClusterVersion, getColl return analyzeClusterVersionResult(k8sVersion, analyzer.Outcomes, analyzer.CheckName) } +func title(checkName string) string { + if checkName == "" { + return "Required Kubernetes Version" + } + + return checkName +} + func analyzeClusterVersionResult(k8sVersion semver.Version, outcomes []*troubleshootv1beta2.Outcome, checkName string) (*AnalyzeResult, error) { for _, outcome := range outcomes { when := "" message := "" uri := "" - title := checkName - if title == "" { - title = "Required Kubernetes Version" - } - result := AnalyzeResult{ - Title: title, + Title: title(checkName), IconKey: "kubernetes_cluster_version", IconURI: "https://troubleshoot.sh/images/analyzer-icons/kubernetes.svg?w=16&h=16", } diff --git a/pkg/analyze/configmap.go b/pkg/analyze/configmap.go index 3641054a3..d1cf05a24 100644 --- a/pkg/analyze/configmap.go +++ b/pkg/analyze/configmap.go @@ -8,7 +8,33 @@ import ( "github.com/replicatedhq/troubleshoot/pkg/collect" ) -func analyzeConfigMap(analyzer *troubleshootv1beta2.AnalyzeConfigMap, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { +type AnalyzeConfigMap struct { + analyzer *troubleshootv1beta2.AnalyzeConfigMap +} + +func (a *AnalyzeConfigMap) Title() string { + title := a.analyzer.CheckName + if title == "" { + title = fmt.Sprintf("ConfigMap %s", a.analyzer.ConfigMapName) + } + + return title +} + +func (a *AnalyzeConfigMap) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeConfigMap) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + result, err := a.analyzeConfigMap(a.analyzer, getFile) + if err != nil { + return nil, err + } + result.Strict = a.analyzer.Strict.BoolOrDefaultFalse() + return []*AnalyzeResult{result}, nil +} + +func (a *AnalyzeConfigMap) analyzeConfigMap(analyzer *troubleshootv1beta2.AnalyzeConfigMap, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { filename := collect.GetConfigMapFileName( &troubleshootv1beta2.ConfigMap{ Namespace: analyzer.Namespace, @@ -28,13 +54,8 @@ func analyzeConfigMap(analyzer *troubleshootv1beta2.AnalyzeConfigMap, getCollect return nil, err } - title := analyzer.CheckName - if title == "" { - title = fmt.Sprintf("ConfigMap %s", analyzer.ConfigMapName) - } - result := AnalyzeResult{ - Title: title, + Title: a.Title(), IconKey: "kubernetes_analyze_secret", // TODO: icon IconURI: "https://troubleshoot.sh/images/analyzer-icons/secret.svg?w=13&h=16", } diff --git a/pkg/analyze/configmap_test.go b/pkg/analyze/configmap_test.go index ebfda9fad..09f951c26 100644 --- a/pkg/analyze/configmap_test.go +++ b/pkg/analyze/configmap_test.go @@ -199,7 +199,12 @@ func Test_analyzeConfigMap(t *testing.T) { } return contents, nil } - got, err := analyzeConfigMap(tt.analyzer, getCollectedFileContents) + + a := AnalyzeConfigMap{ + analyzer: tt.analyzer, + } + + got, err := a.analyzeConfigMap(tt.analyzer, getCollectedFileContents) if tt.wantErr { assert.Error(t, err) } else { diff --git a/pkg/analyze/container_runtime.go b/pkg/analyze/container_runtime.go index 5c03d5ab9..1d4b2b75d 100644 --- a/pkg/analyze/container_runtime.go +++ b/pkg/analyze/container_runtime.go @@ -12,7 +12,33 @@ import ( corev1 "k8s.io/api/core/v1" ) -func analyzeContainerRuntime(analyzer *troubleshootv1beta2.ContainerRuntime, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { +type AnalyzeContainerRuntime struct { + analyzer *troubleshootv1beta2.ContainerRuntime +} + +func (a *AnalyzeContainerRuntime) Title() string { + title := a.analyzer.CheckName + if title == "" { + title = "Container Runtime" + } + + return title +} + +func (a *AnalyzeContainerRuntime) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeContainerRuntime) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + result, err := a.analyzeContainerRuntime(a.analyzer, getFile) + if err != nil { + return nil, err + } + result.Strict = a.analyzer.Strict.BoolOrDefaultFalse() + return []*AnalyzeResult{result}, nil +} + +func (a *AnalyzeContainerRuntime) analyzeContainerRuntime(analyzer *troubleshootv1beta2.ContainerRuntime, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { collected, err := getCollectedFileContents(fmt.Sprintf("%s/%s.json", constants.CLUSTER_RESOURCES_DIR, constants.CLUSTER_RESOURCES_NODES)) if err != nil { return nil, errors.Wrap(err, "failed to get contents of nodes.json") @@ -28,12 +54,8 @@ func analyzeContainerRuntime(analyzer *troubleshootv1beta2.ContainerRuntime, get foundRuntimes = append(foundRuntimes, node.Status.NodeInfo.ContainerRuntimeVersion) } - title := analyzer.CheckName - if title == "" { - title = "Container Runtime" - } result := &AnalyzeResult{ - Title: title, + Title: a.Title(), IconKey: "kubernetes_container_runtime", IconURI: "https://troubleshoot.sh/images/analyzer-icons/container-runtime.svg?w=23&h=16", } diff --git a/pkg/analyze/container_runtime_test.go b/pkg/analyze/container_runtime_test.go index c59571f70..beacc83fa 100644 --- a/pkg/analyze/container_runtime_test.go +++ b/pkg/analyze/container_runtime_test.go @@ -113,7 +113,11 @@ func Test_containerRuntime(t *testing.T) { return test.files[n], nil } - actual, err := analyzeContainerRuntime(&test.analyzer, getFiles) + a := AnalyzeContainerRuntime{ + analyzer: &test.analyzer, + } + + actual, err := a.analyzeContainerRuntime(&test.analyzer, getFiles) req.NoError(err) assert.Equal(t, &test.expectResult, actual) diff --git a/pkg/analyze/crd.go b/pkg/analyze/crd.go index c5b751d30..980ebe505 100644 --- a/pkg/analyze/crd.go +++ b/pkg/analyze/crd.go @@ -9,24 +9,45 @@ import ( apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" ) -func analyzeCustomResourceDefinition(analyzer *troubleshootv1beta2.CustomResourceDefinition, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { - crdData, err := getCollectedFileContents(fmt.Sprintf("%s/%s.json", constants.CLUSTER_RESOURCES_DIR, constants.CLUSTER_RESOURCES_CUSTOM_RESOURCE_DEFINITIONS)) +type AnalyzeCustomResourceDefinition struct { + analyzer *troubleshootv1beta2.CustomResourceDefinition +} + +func (a *AnalyzeCustomResourceDefinition) Title() string { + title := a.analyzer.CheckName + if title == "" { + title = fmt.Sprintf("Custom resource definition %s", a.analyzer.CustomResourceDefinitionName) + } + + return title +} + +func (a *AnalyzeCustomResourceDefinition) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeCustomResourceDefinition) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + result, err := a.analyzeCustomResourceDefinition(a.analyzer, getFile) if err != nil { return nil, err } + result.Strict = a.analyzer.Strict.BoolOrDefaultFalse() + return []*AnalyzeResult{result}, nil +} - var crds apiextensionsv1beta1.CustomResourceDefinitionList - if err := json.Unmarshal(crdData, &crds); err != nil { +func (a *AnalyzeCustomResourceDefinition) analyzeCustomResourceDefinition(analyzer *troubleshootv1beta2.CustomResourceDefinition, getFile getCollectedFileContents) (*AnalyzeResult, error) { + crdData, err := getFile(fmt.Sprintf("%s/%s.json", constants.CLUSTER_RESOURCES_DIR, constants.CLUSTER_RESOURCES_CUSTOM_RESOURCE_DEFINITIONS)) + if err != nil { return nil, err } - title := analyzer.CheckName - if title == "" { - title = fmt.Sprintf("Custom resource definition %s", analyzer.CustomResourceDefinitionName) + var crds apiextensionsv1beta1.CustomResourceDefinitionList + if err := json.Unmarshal(crdData, &crds); err != nil { + return nil, err } result := AnalyzeResult{ - Title: title, + Title: a.Title(), IconKey: "kubernetes_custom_resource_definition", IconURI: "https://troubleshoot.sh/images/analyzer-icons/custom-resource-definition.svg?w=13&h=16", } diff --git a/pkg/analyze/deployment_status.go b/pkg/analyze/deployment_status.go index ca405e399..3302be7ff 100644 --- a/pkg/analyze/deployment_status.go +++ b/pkg/analyze/deployment_status.go @@ -11,6 +11,44 @@ import ( appsv1 "k8s.io/api/apps/v1" ) +type AnalyzeDeploymentStatus struct { + analyzer *troubleshootv1beta2.DeploymentStatus +} + +func (a *AnalyzeDeploymentStatus) Title() string { + if a.analyzer.CheckName != "" { + return a.analyzer.CheckName + } + + if a.analyzer.Name != "" && a.analyzer.Namespace != "" { + return fmt.Sprintf("%s/%s Deployment Status", a.analyzer.Name, a.analyzer.Name) + } + + if a.analyzer.Name != "" { + return fmt.Sprintf("%s Deployment Status", a.analyzer.Name) + } + if a.analyzer.Namespace != "" { + return fmt.Sprintf("%s Deployment Status", a.analyzer.Namespace) + } + + return "Deployment Status" +} + +func (a *AnalyzeDeploymentStatus) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeDeploymentStatus) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + results, err := analyzeDeploymentStatus(a.analyzer, findFiles) + if err != nil { + return nil, err + } + for i := range results { + results[i].Strict = a.analyzer.Strict.BoolOrDefaultFalse() + } + return results, nil +} + func analyzeDeploymentStatus(analyzer *troubleshootv1beta2.DeploymentStatus, getFileContents getChildCollectedFileContents) ([]*AnalyzeResult, error) { if analyzer.Name == "" { return analyzeAllDeploymentStatuses(analyzer, getFileContents) diff --git a/pkg/analyze/distribution.go b/pkg/analyze/distribution.go index 4959b3c0b..656c1ca05 100644 --- a/pkg/analyze/distribution.go +++ b/pkg/analyze/distribution.go @@ -47,6 +47,32 @@ const ( k3s Provider = iota ) +type AnalyzeDistribution struct { + analyzer *troubleshootv1beta2.Distribution +} + +func (a *AnalyzeDistribution) Title() string { + title := a.analyzer.CheckName + if title == "" { + title = "Kubernetes Distribution" + } + + return title +} + +func (a *AnalyzeDistribution) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeDistribution) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + result, err := a.analyzeDistribution(a.analyzer, getFile) + if err != nil { + return nil, err + } + result.Strict = a.analyzer.Strict.BoolOrDefaultFalse() + return []*AnalyzeResult{result}, nil +} + func CheckApiResourcesForProviders(foundProviders *providers, apiResources []*metav1.APIResourceList, provider string) string { for _, resource := range apiResources { if strings.HasPrefix(resource.GroupVersion, "apps.openshift.io/") { @@ -142,7 +168,7 @@ func ParseNodesForProviders(nodes []corev1.Node) (providers, string) { return foundProviders, stringProvider } -func analyzeDistribution(analyzer *troubleshootv1beta2.Distribution, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { +func (a *AnalyzeDistribution) analyzeDistribution(analyzer *troubleshootv1beta2.Distribution, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { var unknownDistribution string collected, err := getCollectedFileContents(fmt.Sprintf("%s/%s.json", constants.CLUSTER_RESOURCES_DIR, constants.CLUSTER_RESOURCES_NODES)) if err != nil { @@ -167,12 +193,8 @@ func analyzeDistribution(analyzer *troubleshootv1beta2.Distribution, getCollecte _ = CheckApiResourcesForProviders(&foundProviders, apiResources, "") } - title := analyzer.CheckName - if title == "" { - title = "Kubernetes Distribution" - } result := &AnalyzeResult{ - Title: title, + Title: a.Title(), IconKey: "kubernetes_distribution", IconURI: "https://troubleshoot.sh/images/analyzer-icons/distribution.svg?w=20&h=14", } diff --git a/pkg/analyze/image_pull_secret.go b/pkg/analyze/image_pull_secret.go index 29139394f..19d3d5c54 100644 --- a/pkg/analyze/image_pull_secret.go +++ b/pkg/analyze/image_pull_secret.go @@ -9,7 +9,33 @@ import ( "github.com/replicatedhq/troubleshoot/pkg/constants" ) -func analyzeImagePullSecret(analyzer *troubleshootv1beta2.ImagePullSecret, getChildCollectedFileContents getChildCollectedFileContents) (*AnalyzeResult, error) { +type AnalyzeImagePullSecret struct { + analyzer *troubleshootv1beta2.ImagePullSecret +} + +func (a *AnalyzeImagePullSecret) Title() string { + title := a.analyzer.CheckName + if title == "" { + title = "Image Pull Secrets" + } + + return title +} + +func (a *AnalyzeImagePullSecret) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeImagePullSecret) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + result, err := a.analyzeImagePullSecret(a.analyzer, findFiles) + if err != nil { + return nil, err + } + result.Strict = a.analyzer.Strict.BoolOrDefaultFalse() + return []*AnalyzeResult{result}, nil +} + +func (a *AnalyzeImagePullSecret) analyzeImagePullSecret(analyzer *troubleshootv1beta2.ImagePullSecret, getChildCollectedFileContents getChildCollectedFileContents) (*AnalyzeResult, error) { var excludeFiles = []string{} imagePullSecrets, err := getChildCollectedFileContents(fmt.Sprintf("%s/%s", constants.CLUSTER_RESOURCES_DIR, constants.CLUSTER_RESOURCES_IMAGE_PULL_SECRETS), excludeFiles) if err != nil { @@ -25,13 +51,9 @@ func analyzeImagePullSecret(analyzer *troubleshootv1beta2.ImagePullSecret, getCh passOutcome = outcome.Pass } } - title := analyzer.CheckName - if title == "" { - title = "Image Pull Secrets" - } result := AnalyzeResult{ - Title: title, + Title: a.Title(), IconKey: "kubernetes_image_pull_secret", IconURI: "https://troubleshoot.sh/images/analyzer-icons/image-pull-secret.svg?w=16&h=14", IsFail: true, diff --git a/pkg/analyze/ingress.go b/pkg/analyze/ingress.go index ea7244eef..862893ecf 100644 --- a/pkg/analyze/ingress.go +++ b/pkg/analyze/ingress.go @@ -10,7 +10,33 @@ import ( extensionsv1beta1 "k8s.io/api/extensions/v1beta1" ) -func analyzeIngress(analyzer *troubleshootv1beta2.Ingress, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { +type AnalyzeIngress struct { + analyzer *troubleshootv1beta2.Ingress +} + +func (a *AnalyzeIngress) Title() string { + title := a.analyzer.CheckName + if title == "" { + title = fmt.Sprintf("Ingress %s", a.analyzer.IngressName) + } + + return title +} + +func (a *AnalyzeIngress) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeIngress) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + result, err := a.analyzeIngress(a.analyzer, getFile) + if err != nil { + return nil, err + } + result.Strict = a.analyzer.Strict.BoolOrDefaultFalse() + return []*AnalyzeResult{result}, nil +} + +func (a *AnalyzeIngress) analyzeIngress(analyzer *troubleshootv1beta2.Ingress, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { ingressData, err := getCollectedFileContents(filepath.Join(constants.CLUSTER_RESOURCES_DIR, constants.CLUSTER_RESOURCES_INGRESS, fmt.Sprintf("%s.json", analyzer.Namespace))) if err != nil { return nil, err @@ -21,13 +47,8 @@ func analyzeIngress(analyzer *troubleshootv1beta2.Ingress, getCollectedFileConte return nil, err } - title := analyzer.CheckName - if title == "" { - title = fmt.Sprintf("Ingress %s", analyzer.IngressName) - } - result := AnalyzeResult{ - Title: title, + Title: a.Title(), IconKey: "kubernetes_ingress", IconURI: "https://troubleshoot.sh/images/analyzer-icons/ingress-controller.svg?w=20&h=13", } diff --git a/pkg/analyze/job_status.go b/pkg/analyze/job_status.go index fdbfc0961..375641961 100644 --- a/pkg/analyze/job_status.go +++ b/pkg/analyze/job_status.go @@ -13,6 +13,44 @@ import ( batchv1 "k8s.io/api/batch/v1" ) +type AnalyzeJobStatus struct { + analyzer *troubleshootv1beta2.JobStatus +} + +func (a *AnalyzeJobStatus) Title() string { + if a.analyzer.CheckName != "" { + return a.analyzer.CheckName + } + + if a.analyzer.Name != "" && a.analyzer.Namespace != "" { + return fmt.Sprintf("%s/%s Job Status", a.analyzer.Namespace, a.analyzer.Name) + } + + if a.analyzer.Name != "" { + return fmt.Sprintf("%s Job Status", a.analyzer.Name) + } + if a.analyzer.Namespace != "" { + return fmt.Sprintf("%s Job Status", a.analyzer.Namespace) + } + + return "Job Status" +} + +func (a *AnalyzeJobStatus) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeJobStatus) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + results, err := analyzeJobStatus(a.analyzer, findFiles) + if err != nil { + return nil, err + } + for i := range results { + results[i].Strict = a.analyzer.Strict.BoolOrDefaultFalse() + } + return results, nil +} + func analyzeJobStatus(analyzer *troubleshootv1beta2.JobStatus, getFileContents getChildCollectedFileContents) ([]*AnalyzeResult, error) { if analyzer.Name == "" { return analyzeAllJobStatuses(analyzer, getFileContents) diff --git a/pkg/analyze/json_compare.go b/pkg/analyze/json_compare.go index 4dc7a112f..242d8cfe0 100644 --- a/pkg/analyze/json_compare.go +++ b/pkg/analyze/json_compare.go @@ -11,7 +11,33 @@ import ( iutils "github.com/replicatedhq/troubleshoot/pkg/interfaceutils" ) -func analyzeJsonCompare(analyzer *troubleshootv1beta2.JsonCompare, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { +type AnalyzeJsonCompare struct { + analyzer *troubleshootv1beta2.JsonCompare +} + +func (a *AnalyzeJsonCompare) Title() string { + title := a.analyzer.CheckName + if title == "" { + title = a.analyzer.CollectorName + } + + return title +} + +func (a *AnalyzeJsonCompare) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeJsonCompare) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + result, err := a.analyzeJsonCompare(a.analyzer, getFile) + if err != nil { + return nil, err + } + result.Strict = a.analyzer.Strict.BoolOrDefaultFalse() + return []*AnalyzeResult{result}, nil +} + +func (a *AnalyzeJsonCompare) analyzeJsonCompare(analyzer *troubleshootv1beta2.JsonCompare, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { fullPath := filepath.Join(analyzer.CollectorName, analyzer.FileName) collected, err := getCollectedFileContents(fullPath) if err != nil { @@ -37,13 +63,8 @@ func analyzeJsonCompare(analyzer *troubleshootv1beta2.JsonCompare, getCollectedF return nil, errors.Wrap(err, "failed to parse expected value as json") } - title := analyzer.CheckName - if title == "" { - title = analyzer.CollectorName - } - result := &AnalyzeResult{ - Title: title, + Title: a.Title(), IconKey: "kubernetes_text_analyze", IconURI: "https://troubleshoot.sh/images/analyzer-icons/text-analyze.svg", } @@ -103,7 +124,7 @@ func analyzeJsonCompare(analyzer *troubleshootv1beta2.JsonCompare, getCollectedF } return &AnalyzeResult{ - Title: title, + Title: a.Title(), IconKey: "kubernetes_text_analyze", IconURI: "https://troubleshoot.sh/images/analyzer-icons/text-analyze.svg", IsFail: true, diff --git a/pkg/analyze/json_compare_test.go b/pkg/analyze/json_compare_test.go index 4fd0bd717..5c7d6f778 100644 --- a/pkg/analyze/json_compare_test.go +++ b/pkg/analyze/json_compare_test.go @@ -551,7 +551,11 @@ func Test_jsonCompare(t *testing.T) { return test.fileContents, nil } - actual, err := analyzeJsonCompare(&test.analyzer, getCollectedFileContents) + a := AnalyzeJsonCompare{ + analyzer: &test.analyzer, + } + + actual, err := a.analyzeJsonCompare(&test.analyzer, getCollectedFileContents) if !test.isError { req.NoError(err) req.Equal(test.expectResult, *actual) diff --git a/pkg/analyze/kube_resource.go b/pkg/analyze/kube_resource.go index f9d82f5de..64a8ae949 100644 --- a/pkg/analyze/kube_resource.go +++ b/pkg/analyze/kube_resource.go @@ -32,6 +32,31 @@ var Filemap = map[string]string{ "StorageClass": fmt.Sprintf("%s.json", constants.CLUSTER_RESOURCES_STORAGE_CLASS), } +type AnalyzeClusterResource struct { + analyzer *troubleshootv1beta2.ClusterResource +} + +func (a *AnalyzeClusterResource) Title() string { + title := a.analyzer.CheckName + if title == "" { + title = a.analyzer.CollectorName + } + + return title +} + +func (a *AnalyzeClusterResource) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeClusterResource) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + result, err := a.analyzeResource(a.analyzer, getFile) + if err != nil { + return nil, err + } + return []*AnalyzeResult{result}, nil +} + // FindResource locates and returns a kubernetes resource as an interface{} from a support bundle based on some basic selectors // if clusterScoped is false and namespace is not provided, it will default to looking in the "default" namespace func FindResource(kind string, clusterScoped bool, namespace string, name string, getFileContents getCollectedFileContents) (interface{}, error) { @@ -82,7 +107,7 @@ func FindResource(kind string, clusterScoped bool, namespace string, name string } -func analyzeResource(analyzer *troubleshootv1beta2.ClusterResource, getFileContents getCollectedFileContents) (*AnalyzeResult, error) { +func (a *AnalyzeClusterResource) analyzeResource(analyzer *troubleshootv1beta2.ClusterResource, getFileContents getCollectedFileContents) (*AnalyzeResult, error) { selected, err := FindResource(analyzer.Kind, analyzer.ClusterScoped, analyzer.Namespace, analyzer.Name, getFileContents) if err != nil { @@ -100,13 +125,8 @@ func analyzeResource(analyzer *troubleshootv1beta2.ClusterResource, getFileConte return nil, errors.Wrap(err, "failed to parse expected value as yaml doc") } - title := analyzer.CheckName - if title == "" { - title = analyzer.CollectorName - } - result := &AnalyzeResult{ - Title: title, + Title: a.Title(), IconKey: "kubernetes_text_analyze", IconURI: "https://troubleshoot.sh/images/analyzer-icons/text-analyze.svg", } @@ -163,7 +183,7 @@ func analyzeResource(analyzer *troubleshootv1beta2.ClusterResource, getFileConte } return &AnalyzeResult{ - Title: title, + Title: a.Title(), IconKey: "kubernetes_text_analyze", IconURI: "https://troubleshoot.sh/images/analyzer-icons/text-analyze.svg", IsFail: true, diff --git a/pkg/analyze/longhorn.go b/pkg/analyze/longhorn.go index bb70a12b6..a9e824452 100644 --- a/pkg/analyze/longhorn.go +++ b/pkg/analyze/longhorn.go @@ -17,6 +17,29 @@ import ( "gopkg.in/yaml.v2" ) +type AnalyzeLonghorn struct { + analyzer *troubleshootv1beta2.LonghornAnalyze +} + +func (a *AnalyzeLonghorn) Title() string { + return "Longhorn analyzer" +} + +func (a *AnalyzeLonghorn) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeLonghorn) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + results, err := longhorn(a.analyzer, getFile, findFiles) + if err != nil { + return nil, err + } + for i := range results { + results[i].Strict = a.analyzer.Strict.BoolOrDefaultFalse() + } + return results, nil +} + func longhorn(analyzer *troubleshootv1beta2.LonghornAnalyze, getFileContents getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { ns := collect.DefaultLonghornNamespace if analyzer.Namespace != "" { diff --git a/pkg/analyze/mysql.go b/pkg/analyze/mysql.go index bd332cddf..94e486b12 100644 --- a/pkg/analyze/mysql.go +++ b/pkg/analyze/mysql.go @@ -10,13 +10,41 @@ import ( "github.com/replicatedhq/troubleshoot/pkg/collect" ) -func analyzeMysql(analyzer *troubleshootv1beta2.DatabaseAnalyze, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { - collectorName := analyzer.CollectorName - if collectorName == "" { - collectorName = "mysql" +type AnalyzeMysql struct { + analyzer *troubleshootv1beta2.DatabaseAnalyze +} + +func (a *AnalyzeMysql) Title() string { + title := a.analyzer.CheckName + if title == "" { + title = a.collectorName() } - fullPath := path.Join("mysql", fmt.Sprintf("%s.json", collectorName)) + return title +} + +func (a *AnalyzeMysql) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeMysql) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + result, err := a.analyzeMysql(a.analyzer, getFile) + if err != nil { + return nil, err + } + result.Strict = a.analyzer.Strict.BoolOrDefaultFalse() + return []*AnalyzeResult{result}, nil +} + +func (a *AnalyzeMysql) collectorName() string { + if a.analyzer.CollectorName != "" { + return a.analyzer.CollectorName + } + return "mysql" +} + +func (a *AnalyzeMysql) analyzeMysql(analyzer *troubleshootv1beta2.DatabaseAnalyze, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { + fullPath := path.Join("mysql", fmt.Sprintf("%s.json", a.collectorName())) collected, err := getCollectedFileContents(fullPath) if err != nil { @@ -28,13 +56,8 @@ func analyzeMysql(analyzer *troubleshootv1beta2.DatabaseAnalyze, getCollectedFil return nil, errors.Wrap(err, "failed to unmarshal databased connection result") } - title := analyzer.CheckName - if title == "" { - title = collectorName - } - result := &AnalyzeResult{ - Title: title, + Title: a.Title(), IconKey: "kubernetes_mysql_analyze", IconURI: "https://troubleshoot.sh/images/analyzer-icons/mysql-analyze.svg", } diff --git a/pkg/analyze/node_resources.go b/pkg/analyze/node_resources.go index ad85d8688..37618e6c3 100644 --- a/pkg/analyze/node_resources.go +++ b/pkg/analyze/node_resources.go @@ -14,7 +14,33 @@ import ( "k8s.io/apimachinery/pkg/api/resource" ) -func analyzeNodeResources(analyzer *troubleshootv1beta2.NodeResources, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { +type AnalyzeNodeResources struct { + analyzer *troubleshootv1beta2.NodeResources +} + +func (a *AnalyzeNodeResources) Title() string { + title := a.analyzer.CheckName + if title == "" { + title = "Node Resources" + } + + return title +} + +func (a *AnalyzeNodeResources) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeNodeResources) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + result, err := a.analyzeNodeResources(a.analyzer, getFile) + if err != nil { + return nil, err + } + result.Strict = a.analyzer.Strict.BoolOrDefaultFalse() + return []*AnalyzeResult{result}, nil +} + +func (a *AnalyzeNodeResources) analyzeNodeResources(analyzer *troubleshootv1beta2.NodeResources, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { collected, err := getCollectedFileContents(fmt.Sprintf("%s/%s.json", constants.CLUSTER_RESOURCES_DIR, constants.CLUSTER_RESOURCES_NODES)) if err != nil { return nil, errors.Wrap(err, "failed to get contents of nodes.json") @@ -38,13 +64,8 @@ func analyzeNodeResources(analyzer *troubleshootv1beta2.NodeResources, getCollec } } - title := analyzer.CheckName - if title == "" { - title = "Node Resources" - } - result := &AnalyzeResult{ - Title: title, + Title: a.Title(), IconKey: "kubernetes_node_resources", IconURI: "https://troubleshoot.sh/images/analyzer-icons/node-resources.svg?w=16&h=18", } diff --git a/pkg/analyze/node_resources_test.go b/pkg/analyze/node_resources_test.go index 0aeacc9cf..ac8b1c0fa 100644 --- a/pkg/analyze/node_resources_test.go +++ b/pkg/analyze/node_resources_test.go @@ -936,7 +936,11 @@ func Test_analyzeNodeResources(t *testing.T) { t.Run(tt.name, func(t *testing.T) { req := require.New(t) - got, err := analyzeNodeResources(tt.analyzer, getExampleNodeContents) + a := AnalyzeNodeResources{ + analyzer: tt.analyzer, + } + + got, err := a.analyzeNodeResources(tt.analyzer, getExampleNodeContents) req.NoError(err) req.Equal(tt.want, got) }) diff --git a/pkg/analyze/postgres.go b/pkg/analyze/postgres.go index 9b15ce856..15a6e0501 100644 --- a/pkg/analyze/postgres.go +++ b/pkg/analyze/postgres.go @@ -10,13 +10,43 @@ import ( "github.com/replicatedhq/troubleshoot/pkg/collect" ) -func analyzePostgres(analyzer *troubleshootv1beta2.DatabaseAnalyze, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { - collectorName := analyzer.CollectorName +type AnalyzePostgres struct { + analyzer *troubleshootv1beta2.DatabaseAnalyze +} + +func (a *AnalyzePostgres) Title() string { + title := a.analyzer.CheckName + if title == "" { + title = a.collectorName() + } + + return title +} + +func (a *AnalyzePostgres) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzePostgres) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + result, err := a.analyzePostgres(a.analyzer, getFile) + if err != nil { + return nil, err + } + result.Strict = a.analyzer.Strict.BoolOrDefaultFalse() + return []*AnalyzeResult{result}, nil +} + +func (a *AnalyzePostgres) collectorName() string { + collectorName := a.analyzer.CollectorName if collectorName == "" { collectorName = "postgres" } - fullPath := path.Join("postgres", fmt.Sprintf("%s.json", collectorName)) + return collectorName +} + +func (a *AnalyzePostgres) analyzePostgres(analyzer *troubleshootv1beta2.DatabaseAnalyze, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { + fullPath := path.Join("postgres", fmt.Sprintf("%s.json", a.collectorName())) collected, err := getCollectedFileContents(fullPath) if err != nil { @@ -28,13 +58,8 @@ func analyzePostgres(analyzer *troubleshootv1beta2.DatabaseAnalyze, getCollected return nil, errors.Wrap(err, "failed to unmarshal databased connection result") } - title := analyzer.CheckName - if title == "" { - title = collectorName - } - result := &AnalyzeResult{ - Title: title, + Title: a.Title(), IconKey: "kubernetes_postgres_analyze", IconURI: "https://troubleshoot.sh/images/analyzer-icons/postgres-analyze.svg", } diff --git a/pkg/analyze/redis.go b/pkg/analyze/redis.go index a9bd63354..b8cf6b592 100644 --- a/pkg/analyze/redis.go +++ b/pkg/analyze/redis.go @@ -10,13 +10,43 @@ import ( "github.com/replicatedhq/troubleshoot/pkg/collect" ) -func analyzeRedis(analyzer *troubleshootv1beta2.DatabaseAnalyze, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { - collectorName := analyzer.CollectorName +type AnalyzeRedis struct { + analyzer *troubleshootv1beta2.DatabaseAnalyze +} + +func (a *AnalyzeRedis) Title() string { + title := a.analyzer.CheckName + if title == "" { + title = a.collectorName() + } + + return title +} + +func (a *AnalyzeRedis) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeRedis) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + result, err := a.analyzeRedis(a.analyzer, getFile) + if err != nil { + return nil, err + } + result.Strict = a.analyzer.Strict.BoolOrDefaultFalse() + return []*AnalyzeResult{result}, nil +} + +func (a *AnalyzeRedis) collectorName() string { + collectorName := a.analyzer.CollectorName if collectorName == "" { collectorName = "redis" } - fullPath := path.Join("redis", fmt.Sprintf("%s.json", collectorName)) + return collectorName +} + +func (a *AnalyzeRedis) analyzeRedis(analyzer *troubleshootv1beta2.DatabaseAnalyze, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { + fullPath := path.Join("redis", fmt.Sprintf("%s.json", a.collectorName())) collected, err := getCollectedFileContents(fullPath) if err != nil { @@ -28,13 +58,8 @@ func analyzeRedis(analyzer *troubleshootv1beta2.DatabaseAnalyze, getCollectedFil return nil, errors.Wrap(err, "failed to unmarshal database connection result") } - title := analyzer.CheckName - if title == "" { - title = collectorName - } - result := &AnalyzeResult{ - Title: title, + Title: a.Title(), IconKey: "kubernetes_redis_analyze", IconURI: "https://troubleshoot.sh/images/analyzer-icons/redis-analyze.svg", } diff --git a/pkg/analyze/registry.go b/pkg/analyze/registry.go index eb25e7b4f..abababd89 100644 --- a/pkg/analyze/registry.go +++ b/pkg/analyze/registry.go @@ -12,13 +12,43 @@ import ( "github.com/replicatedhq/troubleshoot/pkg/collect" ) -func analyzeRegistry(analyzer *troubleshootv1beta2.RegistryImagesAnalyze, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { - collectorName := analyzer.CollectorName +type AnalyzeRegistryImages struct { + analyzer *troubleshootv1beta2.RegistryImagesAnalyze +} + +func (a *AnalyzeRegistryImages) Title() string { + title := a.analyzer.CheckName + if title == "" { + title = a.collectorName() + } + + return title +} + +func (a *AnalyzeRegistryImages) collectorName() string { + collectorName := a.analyzer.CollectorName if collectorName == "" { collectorName = "images" } - fullPath := path.Join("registry", fmt.Sprintf("%s.json", collectorName)) + return collectorName +} + +func (a *AnalyzeRegistryImages) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeRegistryImages) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + result, err := a.analyzeRegistry(a.analyzer, getFile) + if err != nil { + return nil, err + } + result.Strict = a.analyzer.Strict.BoolOrDefaultFalse() + return []*AnalyzeResult{result}, nil +} + +func (a *AnalyzeRegistryImages) analyzeRegistry(analyzer *troubleshootv1beta2.RegistryImagesAnalyze, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { + fullPath := path.Join("registry", fmt.Sprintf("%s.json", a.collectorName())) collected, err := getCollectedFileContents(fullPath) if err != nil { @@ -43,13 +73,8 @@ func analyzeRegistry(analyzer *troubleshootv1beta2.RegistryImagesAnalyze, getCol } } - title := analyzer.CheckName - if title == "" { - title = collectorName - } - result := &AnalyzeResult{ - Title: title, + Title: a.Title(), IconKey: "kubernetes_registry_analyze", IconURI: "https://troubleshoot.sh/images/analyzer-icons/registry-analyze.svg", } diff --git a/pkg/analyze/replicaset_status.go b/pkg/analyze/replicaset_status.go index ca5e7d2f0..d4bc2758e 100644 --- a/pkg/analyze/replicaset_status.go +++ b/pkg/analyze/replicaset_status.go @@ -14,6 +14,44 @@ import ( "k8s.io/apimachinery/pkg/labels" ) +type AnalyzeReplicaSetStatus struct { + analyzer *troubleshootv1beta2.ReplicaSetStatus +} + +func (a *AnalyzeReplicaSetStatus) Title() string { + if a.analyzer.CheckName != "" { + return a.analyzer.CheckName + } + + if a.analyzer.Name != "" && a.analyzer.Namespace != "" { + return fmt.Sprintf("%s/%s ReplicaSet Status", a.analyzer.Namespace, a.analyzer.Name) + } + + if a.analyzer.Name != "" { + return fmt.Sprintf("%s ReplicaSet Status", a.analyzer.Name) + } + if a.analyzer.Namespace != "" { + return fmt.Sprintf("%s ReplicaSet Status", a.analyzer.Namespace) + } + + return "ReplicaSet Status" +} + +func (a *AnalyzeReplicaSetStatus) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeReplicaSetStatus) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + results, err := analyzeReplicaSetStatus(a.analyzer, findFiles) + if err != nil { + return nil, err + } + for i := range results { + results[i].Strict = a.analyzer.Strict.BoolOrDefaultFalse() + } + return results, nil +} + func analyzeReplicaSetStatus(analyzer *troubleshootv1beta2.ReplicaSetStatus, getFileContents getChildCollectedFileContents) ([]*AnalyzeResult, error) { if analyzer.Name == "" { return analyzeAllReplicaSetStatuses(analyzer, getFileContents) diff --git a/pkg/analyze/secret.go b/pkg/analyze/secret.go index e4f51285b..324860646 100644 --- a/pkg/analyze/secret.go +++ b/pkg/analyze/secret.go @@ -8,7 +8,33 @@ import ( "github.com/replicatedhq/troubleshoot/pkg/collect" ) -func analyzeSecret(analyzer *troubleshootv1beta2.AnalyzeSecret, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { +type AnalyzeSecret struct { + analyzer *troubleshootv1beta2.AnalyzeSecret +} + +func (a *AnalyzeSecret) Title() string { + title := a.analyzer.CheckName + if title == "" { + title = fmt.Sprintf("Secret %s", a.analyzer.SecretName) + } + + return title +} + +func (a *AnalyzeSecret) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeSecret) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + result, err := a.analyzeSecret(a.analyzer, getFile) + if err != nil { + return nil, err + } + result.Strict = a.analyzer.Strict.BoolOrDefaultFalse() + return []*AnalyzeResult{result}, nil +} + +func (a *AnalyzeSecret) analyzeSecret(analyzer *troubleshootv1beta2.AnalyzeSecret, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { filename := collect.GetSecretFileName( &troubleshootv1beta2.Secret{ Namespace: analyzer.Namespace, @@ -28,13 +54,8 @@ func analyzeSecret(analyzer *troubleshootv1beta2.AnalyzeSecret, getCollectedFile return nil, err } - title := analyzer.CheckName - if title == "" { - title = fmt.Sprintf("Secret %s", analyzer.SecretName) - } - result := AnalyzeResult{ - Title: title, + Title: a.Title(), IconKey: "kubernetes_analyze_secret", IconURI: "https://troubleshoot.sh/images/analyzer-icons/secret.svg?w=13&h=16", } diff --git a/pkg/analyze/secret_test.go b/pkg/analyze/secret_test.go index 8744b7ee8..f8945f1e7 100644 --- a/pkg/analyze/secret_test.go +++ b/pkg/analyze/secret_test.go @@ -200,7 +200,10 @@ func Test_analyzeSecret(t *testing.T) { } return contents, nil } - got, err := analyzeSecret(tt.analyzer, getCollectedFileContents) + a := AnalyzeSecret{ + analyzer: tt.analyzer, + } + got, err := a.analyzeSecret(tt.analyzer, getCollectedFileContents) if tt.wantErr { assert.Error(t, err) } else { diff --git a/pkg/analyze/statefulset_status.go b/pkg/analyze/statefulset_status.go index d2836db2d..1c874163f 100644 --- a/pkg/analyze/statefulset_status.go +++ b/pkg/analyze/statefulset_status.go @@ -11,6 +11,44 @@ import ( appsv1 "k8s.io/api/apps/v1" ) +type AnalyzeStatefulsetStatus struct { + analyzer *troubleshootv1beta2.StatefulsetStatus +} + +func (a *AnalyzeStatefulsetStatus) Title() string { + if a.analyzer.CheckName != "" { + return a.analyzer.CheckName + } + + if a.analyzer.Name != "" && a.analyzer.Namespace != "" { + return fmt.Sprintf("%s/%s Statefulset Status", a.analyzer.Namespace, a.analyzer.Name) + } + + if a.analyzer.Name != "" { + return fmt.Sprintf("%s Statefulset Status", a.analyzer.Name) + } + if a.analyzer.Namespace != "" { + return fmt.Sprintf("%s Statefulset Status", a.analyzer.Namespace) + } + + return "Statefulset Status" +} + +func (a *AnalyzeStatefulsetStatus) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeStatefulsetStatus) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + results, err := analyzeStatefulsetStatus(a.analyzer, findFiles) + if err != nil { + return nil, err + } + for i := range results { + results[i].Strict = a.analyzer.Strict.BoolOrDefaultFalse() + } + return results, nil +} + func analyzeStatefulsetStatus(analyzer *troubleshootv1beta2.StatefulsetStatus, getFileContents getChildCollectedFileContents) ([]*AnalyzeResult, error) { if analyzer.Name == "" { return analyzeAllStatefulsetStatuses(analyzer, getFileContents) diff --git a/pkg/analyze/storage_class.go b/pkg/analyze/storage_class.go index 450c6a671..f9564d578 100644 --- a/pkg/analyze/storage_class.go +++ b/pkg/analyze/storage_class.go @@ -9,7 +9,37 @@ import ( storagev1beta1 "k8s.io/api/storage/v1beta1" ) -func analyzeStorageClass(analyzer *troubleshootv1beta2.StorageClass, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { +type AnalyzeStorageClass struct { + analyzer *troubleshootv1beta2.StorageClass +} + +func (a *AnalyzeStorageClass) Title() string { + title := a.analyzer.CheckName + if title == "" { + if a.analyzer.StorageClassName != "" { + title = fmt.Sprintf("Storage class %s", a.analyzer.StorageClassName) + } else { + title = "Default Storage Class" + } + } + + return title +} + +func (a *AnalyzeStorageClass) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeStorageClass) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + result, err := a.analyzeStorageClass(a.analyzer, getFile) + if err != nil { + return nil, err + } + result.Strict = a.analyzer.Strict.BoolOrDefaultFalse() + return []*AnalyzeResult{result}, nil +} + +func (a *AnalyzeStorageClass) analyzeStorageClass(analyzer *troubleshootv1beta2.StorageClass, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { storageClassesData, err := getCollectedFileContents(fmt.Sprintf("%s/%s.json", constants.CLUSTER_RESOURCES_DIR, constants.CLUSTER_RESOURCES_STORAGE_CLASS)) if err != nil { return nil, err @@ -20,23 +50,14 @@ func analyzeStorageClass(analyzer *troubleshootv1beta2.StorageClass, getCollecte return nil, err } - title := analyzer.CheckName - if title == "" { - if analyzer.StorageClassName != "" { - title = fmt.Sprintf("Storage class %s", analyzer.StorageClassName) - } else { - title = "Default Storage Class" - } - } - result := AnalyzeResult{ - Title: title, + Title: a.Title(), IconKey: "kubernetes_storage_class", IconURI: "https://troubleshoot.sh/images/analyzer-icons/storage-class.svg?w=12&h=12", } for _, storageClass := range storageClasses.Items { - val, _ := storageClass.Annotations["storageclass.kubernetes.io/is-default-class"] + val := storageClass.Annotations["storageclass.kubernetes.io/is-default-class"] if (storageClass.Name == analyzer.StorageClassName) || (analyzer.StorageClassName == "" && val == "true") { result.IsPass = true for _, outcome := range analyzer.Outcomes { diff --git a/pkg/analyze/sysctl.go b/pkg/analyze/sysctl.go index 9ab717b99..98263d76a 100644 --- a/pkg/analyze/sysctl.go +++ b/pkg/analyze/sysctl.go @@ -14,10 +14,34 @@ import ( troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" ) +type AnalyzeSysctl struct { + analyzer *troubleshootv1beta2.SysctlAnalyze +} + +func (a *AnalyzeSysctl) Title() string { + return "Sysctl" +} + +func (a *AnalyzeSysctl) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeSysctl) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + result, err := a.analyzeSysctl(a.analyzer, findFiles) + if err != nil { + return nil, err + } + if result == nil { + return []*AnalyzeResult{}, nil + } + result.Strict = a.analyzer.Strict.BoolOrDefaultFalse() + return []*AnalyzeResult{result}, nil +} + // The when condition for outcomes in this analyzer is interpreted as "for some node". // For example, "when: net.ipv4.ip_forward = 0" is true if at least one node has IP forwarding // disabled. -func analyzeSysctl(analyzer *troubleshootv1beta2.SysctlAnalyze, findFiles getChildCollectedFileContents) (*AnalyzeResult, error) { +func (a *AnalyzeSysctl) analyzeSysctl(analyzer *troubleshootv1beta2.SysctlAnalyze, findFiles getChildCollectedFileContents) (*AnalyzeResult, error) { excludeFiles := []string{} files, err := findFiles("sysctl/*", excludeFiles) if err != nil { @@ -42,7 +66,7 @@ func analyzeSysctl(analyzer *troubleshootv1beta2.SysctlAnalyze, findFiles getChi if result != nil { result.Title = analyzer.CheckName if result.Title == "" { - result.Title = "Sysctl" + result.Title = a.Title() } return result, nil } diff --git a/pkg/analyze/sysctl_test.go b/pkg/analyze/sysctl_test.go index 6e1599f44..670d218ac 100644 --- a/pkg/analyze/sysctl_test.go +++ b/pkg/analyze/sysctl_test.go @@ -403,7 +403,11 @@ func TestAnalyzeSysctl(t *testing.T) { var findFiles = func(glob string, _ []string) (map[string][]byte, error) { return test.files, nil } - got, err := analyzeSysctl(test.analyzer, findFiles) + + a := AnalyzeSysctl{ + analyzer: test.analyzer, + } + got, err := a.analyzeSysctl(test.analyzer, findFiles) assert.NoError(t, err) diff --git a/pkg/analyze/text_analyze.go b/pkg/analyze/text_analyze.go index 6e14f6fdd..31b63da07 100644 --- a/pkg/analyze/text_analyze.go +++ b/pkg/analyze/text_analyze.go @@ -13,7 +13,35 @@ import ( troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" ) -func analyzeTextAnalyze(analyzer *troubleshootv1beta2.TextAnalyze, getCollectedFileContents getChildCollectedFileContents) ([]*AnalyzeResult, error) { +type AnalyzeTextAnalyze struct { + analyzer *troubleshootv1beta2.TextAnalyze +} + +func (a *AnalyzeTextAnalyze) Title() string { + checkName := a.analyzer.CheckName + if checkName == "" { + checkName = a.analyzer.CollectorName + } + + return checkName +} + +func (a *AnalyzeTextAnalyze) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeTextAnalyze) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + results, err := a.analyzeTextAnalyze(a.analyzer, findFiles) + if err != nil { + return nil, err + } + for i := range results { + results[i].Strict = a.analyzer.Strict.BoolOrDefaultFalse() + } + return results, nil +} + +func (a *AnalyzeTextAnalyze) analyzeTextAnalyze(analyzer *troubleshootv1beta2.TextAnalyze, getCollectedFileContents getChildCollectedFileContents) ([]*AnalyzeResult, error) { fullPath := filepath.Join(analyzer.CollectorName, analyzer.FileName) excludeFiles := []string{} for _, excludeFile := range analyzer.ExcludeFiles { @@ -25,11 +53,6 @@ func analyzeTextAnalyze(analyzer *troubleshootv1beta2.TextAnalyze, getCollectedF return nil, errors.Wrapf(err, "failed to read collected file name: %s", fullPath) } - checkName := analyzer.CheckName - if checkName == "" { - checkName = analyzer.CollectorName - } - if len(collected) == 0 { if analyzer.IgnoreIfNoFiles { return nil, nil @@ -37,7 +60,7 @@ func analyzeTextAnalyze(analyzer *troubleshootv1beta2.TextAnalyze, getCollectedF return []*AnalyzeResult{ { - Title: checkName, + Title: a.Title(), IconKey: "kubernetes_text_analyze", IconURI: "https://troubleshoot.sh/images/analyzer-icons/text-analyze.svg", IsWarn: true, @@ -50,7 +73,7 @@ func analyzeTextAnalyze(analyzer *troubleshootv1beta2.TextAnalyze, getCollectedF if analyzer.RegexPattern != "" { for _, fileContents := range collected { - result, err := analyzeRegexPattern(analyzer.RegexPattern, fileContents, analyzer.Outcomes, checkName) + result, err := analyzeRegexPattern(analyzer.RegexPattern, fileContents, analyzer.Outcomes, a.Title()) if err != nil { return nil, err } @@ -62,7 +85,7 @@ func analyzeTextAnalyze(analyzer *troubleshootv1beta2.TextAnalyze, getCollectedF if analyzer.RegexGroups != "" { for _, fileContents := range collected { - result, err := analyzeRegexGroups(analyzer.RegexGroups, fileContents, analyzer.Outcomes, checkName) + result, err := analyzeRegexGroups(analyzer.RegexGroups, fileContents, analyzer.Outcomes, a.Title()) if err != nil { return nil, err } @@ -78,7 +101,7 @@ func analyzeTextAnalyze(analyzer *troubleshootv1beta2.TextAnalyze, getCollectedF return []*AnalyzeResult{ { - Title: checkName, + Title: a.Title(), IconKey: "kubernetes_text_analyze", IconURI: "https://troubleshoot.sh/images/analyzer-icons/text-analyze.svg", IsFail: true, diff --git a/pkg/analyze/text_analyze_test.go b/pkg/analyze/text_analyze_test.go index 17822ff96..eab5eb0a0 100644 --- a/pkg/analyze/text_analyze_test.go +++ b/pkg/analyze/text_analyze_test.go @@ -727,7 +727,11 @@ func Test_textAnalyze(t *testing.T) { return matching, nil } - actual, err := analyzeTextAnalyze(&test.analyzer, getFiles) + a := AnalyzeTextAnalyze{ + analyzer: &test.analyzer, + } + + actual, err := a.analyzeTextAnalyze(&test.analyzer, getFiles) req.NoError(err) unPointered := []AnalyzeResult{} diff --git a/pkg/analyze/weave.go b/pkg/analyze/weave.go index fd7462e81..9dc179198 100644 --- a/pkg/analyze/weave.go +++ b/pkg/analyze/weave.go @@ -39,6 +39,29 @@ type WeaveAttributes struct { Name string `json:"name"` } +type AnalyzeWeaveReport struct { + analyzer *troubleshootv1beta2.WeaveReportAnalyze +} + +func (a *AnalyzeWeaveReport) Title() string { + return "Weave CNI" +} + +func (a *AnalyzeWeaveReport) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeWeaveReport) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + results, err := analyzeWeaveReport(a.analyzer, findFiles) + if err != nil { + return nil, err + } + for i := range results { + results[i].Strict = a.analyzer.Strict.BoolOrDefaultFalse() + } + return results, nil +} + func analyzeWeaveReport(analyzer *troubleshootv1beta2.WeaveReportAnalyze, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { excludeFiles := []string{} files, err := findFiles(analyzer.ReportFileGlob, excludeFiles) diff --git a/pkg/analyze/yaml_compare.go b/pkg/analyze/yaml_compare.go index 9b72affb4..1a9760bf0 100644 --- a/pkg/analyze/yaml_compare.go +++ b/pkg/analyze/yaml_compare.go @@ -11,7 +11,33 @@ import ( "gopkg.in/yaml.v2" ) -func analyzeYamlCompare(analyzer *troubleshootv1beta2.YamlCompare, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { +type AnalyzeYamlCompare struct { + analyzer *troubleshootv1beta2.YamlCompare +} + +func (a *AnalyzeYamlCompare) Title() string { + title := a.analyzer.CheckName + if title == "" { + title = a.analyzer.CollectorName + } + + return title +} + +func (a *AnalyzeYamlCompare) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeYamlCompare) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + result, err := a.analyzeYamlCompare(a.analyzer, getFile) + if err != nil { + return nil, err + } + result.Strict = a.analyzer.Strict.BoolOrDefaultFalse() + return []*AnalyzeResult{result}, nil +} + +func (a *AnalyzeYamlCompare) analyzeYamlCompare(analyzer *troubleshootv1beta2.YamlCompare, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { fullPath := filepath.Join(analyzer.CollectorName, analyzer.FileName) collected, err := getCollectedFileContents(fullPath) if err != nil { @@ -37,13 +63,8 @@ func analyzeYamlCompare(analyzer *troubleshootv1beta2.YamlCompare, getCollectedF return nil, errors.Wrap(err, "failed to parse expected value as yaml doc") } - title := analyzer.CheckName - if title == "" { - title = analyzer.CollectorName - } - result := &AnalyzeResult{ - Title: title, + Title: a.Title(), IconKey: "kubernetes_text_analyze", IconURI: "https://troubleshoot.sh/images/analyzer-icons/text-analyze.svg", } @@ -100,7 +121,7 @@ func analyzeYamlCompare(analyzer *troubleshootv1beta2.YamlCompare, getCollectedF } return &AnalyzeResult{ - Title: title, + Title: a.Title(), IconKey: "kubernetes_text_analyze", IconURI: "https://troubleshoot.sh/images/analyzer-icons/text-analyze.svg", IsFail: true, diff --git a/pkg/analyze/yaml_compare_test.go b/pkg/analyze/yaml_compare_test.go index 737f4a790..f7d43941a 100644 --- a/pkg/analyze/yaml_compare_test.go +++ b/pkg/analyze/yaml_compare_test.go @@ -440,7 +440,11 @@ otherstuff: return test.fileContents, nil } - actual, err := analyzeYamlCompare(&test.analyzer, getCollectedFileContents) + a := AnalyzeYamlCompare{ + analyzer: &test.analyzer, + } + + actual, err := a.analyzeYamlCompare(&test.analyzer, getCollectedFileContents) if !test.isError { req.NoError(err) req.Equal(test.expectResult, *actual) diff --git a/pkg/constants/constants.go b/pkg/constants/constants.go index 0238224dc..40f1781ba 100644 --- a/pkg/constants/constants.go +++ b/pkg/constants/constants.go @@ -33,7 +33,7 @@ const ( CLUSTER_RESOURCES_STORAGE_CLASS = "storage-classes" CLUSTER_RESOURCES_CUSTOM_RESOURCE_DEFINITIONS = "custom-resource-definitions" CLUSTER_RESOURCES_CUSTOM_RESOURCES = "custom-resources" - CLUSTER_RESOURCES_IMAGE_PULL_SECRETS = "image-pull-secrets" + CLUSTER_RESOURCES_IMAGE_PULL_SECRETS = "image-pull-secrets" // nolint:gosec CLUSTER_RESOURCES_NODES = "nodes" CLUSTER_RESOURCES_GROUPS = "groups" CLUSTER_RESOURCES_RESOURCES = "resources" From 7c3b5d081cb8d6cdfd2a7a77abdb9d7c83788efc Mon Sep 17 00:00:00 2001 From: Chase Hainey Date: Mon, 20 Mar 2023 12:39:50 -0600 Subject: [PATCH 21/55] 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 --- Makefile | 15 +- cmd/preflight/cli/root.go | 16 +- cmd/troubleshoot/cli/root.go | 17 +- cmd/troubleshoot/cli/version.go | 2 +- .../support-bundle/sample-supportbundle.yaml | 2 + go.mod | 6 +- go.sum | 9 + internal/traces/exporter.go | 273 ++++++++++++++++++ internal/traces/exporter_test.go | 187 ++++++++++++ internal/traces/otel.go | 60 ++++ pkg/analyze/analyzer.go | 34 ++- pkg/analyze/analyzer_test.go | 3 +- pkg/analyze/download.go | 20 +- pkg/collect/host_udpportstatus_test.go | 4 - pkg/constants/constants.go | 10 +- pkg/preflight/analyze.go | 19 +- pkg/preflight/collect.go | 59 +++- pkg/preflight/run.go | 30 +- pkg/supportbundle/collect.go | 45 ++- pkg/supportbundle/supportbundle.go | 44 ++- 20 files changed, 795 insertions(+), 60 deletions(-) create mode 100644 internal/traces/exporter.go create mode 100644 internal/traces/exporter_test.go create mode 100644 internal/traces/otel.go diff --git a/Makefile b/Makefile index 196004348..e472bf82f 100644 --- a/Makefile +++ b/Makefile @@ -35,6 +35,7 @@ define LDFLAGS endef BUILDFLAGS = -tags "netgo containers_image_ostree_stub exclude_graphdriver_devicemapper exclude_graphdriver_btrfs containers_image_openpgp" -installsuffix netgo +BUILDPATHS = ./pkg/... ./cmd/... ./internal/... all: test support-bundle preflight collect analyze @@ -45,16 +46,16 @@ ffi: fmt vet .PHONY: test test: generate fmt vet if [ -n $(RUN) ]; then \ - go test ${BUILDFLAGS} ./pkg/... ./cmd/... -coverprofile cover.out -run $(RUN); \ + go test ${BUILDFLAGS} ${BUILDPATHS} -coverprofile cover.out -run $(RUN); \ else \ - go test ${BUILDFLAGS} ./pkg/... ./cmd/... -coverprofile cover.out; \ + go test ${BUILDFLAGS} ${BUILDPATHS} -coverprofile cover.out; \ fi # 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" ./pkg/... ./cmd/... + go test -v --tags "integration exclude_graphdriver_devicemapper exclude_graphdriver_btrfs" ${BUILDPATHS} .PHONY: preflight-e2e-test preflight-e2e-test: @@ -82,11 +83,11 @@ collect: .PHONY: fmt fmt: - go fmt ./pkg/... ./cmd/... + go fmt ${BUILDPATHS} .PHONY: vet vet: - go vet ${BUILDFLAGS} ./pkg/... ./cmd/... + go vet ${BUILDFLAGS} ${BUILDPATHS} .PHONY: generate generate: controller-gen client-gen @@ -213,8 +214,8 @@ scan: .PHONY: lint lint: - golangci-lint run --new -c .golangci.yaml pkg/... cmd/... + golangci-lint run --new -c .golangci.yaml ${BUILDPATHS} .PHONY: lint-and-fix lint-and-fix: - golangci-lint run --new --fix -c .golangci.yaml pkg/... cmd/... + golangci-lint run --new --fix -c .golangci.yaml ${BUILDPATHS} diff --git a/cmd/preflight/cli/root.go b/cmd/preflight/cli/root.go index 41dd9bca7..12d91c614 100644 --- a/cmd/preflight/cli/root.go +++ b/cmd/preflight/cli/root.go @@ -1,11 +1,13 @@ package cli import ( + "fmt" "os" "strings" "github.com/go-logr/logr" "github.com/replicatedhq/troubleshoot/cmd/util" + "github.com/replicatedhq/troubleshoot/internal/traces" "github.com/replicatedhq/troubleshoot/pkg/k8sutil" "github.com/replicatedhq/troubleshoot/pkg/logger" "github.com/replicatedhq/troubleshoot/pkg/preflight" @@ -37,7 +39,19 @@ that a cluster meets the requirements to run an application.`, }, RunE: func(cmd *cobra.Command, args []string) error { v := viper.GetViper() - return preflight.RunPreflights(v.GetBool("interactive"), v.GetString("output"), v.GetString("format"), args) + closer, err := traces.ConfigureTracing("preflight") + if err != nil { + // Do not fail running preflights if tracing fails + logger.Printf("Failed to initialize open tracing provider: %v", err) + } else { + defer closer() + } + + err = preflight.RunPreflights(v.GetBool("interactive"), v.GetString("output"), v.GetString("format"), args) + if v.GetBool("debug") { + fmt.Printf("\n%s", traces.GetExporterInstance().GetSummary()) + } + return err }, PostRun: func(cmd *cobra.Command, args []string) { if err := util.StopProfiling(); err != nil { diff --git a/cmd/troubleshoot/cli/root.go b/cmd/troubleshoot/cli/root.go index 3e4f2a712..0e52b4b64 100644 --- a/cmd/troubleshoot/cli/root.go +++ b/cmd/troubleshoot/cli/root.go @@ -1,11 +1,13 @@ package cli import ( + "fmt" "os" "strings" "github.com/go-logr/logr" "github.com/replicatedhq/troubleshoot/cmd/util" + "github.com/replicatedhq/troubleshoot/internal/traces" "github.com/replicatedhq/troubleshoot/pkg/k8sutil" "github.com/replicatedhq/troubleshoot/pkg/logger" "github.com/spf13/cobra" @@ -40,7 +42,20 @@ from a server that can be used to assist when troubleshooting a Kubernetes clust RunE: func(cmd *cobra.Command, args []string) error { v := viper.GetViper() - return runTroubleshoot(v, args) + closer, err := traces.ConfigureTracing("support-bundle") + if err != nil { + // Do not fail running support-bundle if tracing fails + logger.Printf("Failed to initialize open tracing provider: %v", err) + } else { + defer closer() + } + + err = runTroubleshoot(v, args) + if v.GetBool("debug") { + fmt.Printf("\n%s", traces.GetExporterInstance().GetSummary()) + } + + return err }, PersistentPostRun: func(cmd *cobra.Command, args []string) { if err := util.StopProfiling(); err != nil { diff --git a/cmd/troubleshoot/cli/version.go b/cmd/troubleshoot/cli/version.go index 7baf58055..38bb26d17 100644 --- a/cmd/troubleshoot/cli/version.go +++ b/cmd/troubleshoot/cli/version.go @@ -40,7 +40,7 @@ func writeVersionFile(path string) error { return err } - filename := filepath.Join(path, constants.VersionFilename) + filename := filepath.Join(path, constants.VERSION_FILENAME) err = ioutil.WriteFile(filename, b, 0644) if err != nil { return err diff --git a/examples/support-bundle/sample-supportbundle.yaml b/examples/support-bundle/sample-supportbundle.yaml index 3baf560c7..c395b0ddd 100644 --- a/examples/support-bundle/sample-supportbundle.yaml +++ b/examples/support-bundle/sample-supportbundle.yaml @@ -3,6 +3,8 @@ kind: SupportBundle metadata: name: example spec: + hostCollectors: + - hostOS: {} collectors: - logs: selector: diff --git a/go.mod b/go.mod index 8c89b8ffc..36fca2eab 100644 --- a/go.mod +++ b/go.mod @@ -34,6 +34,8 @@ require ( github.com/spf13/viper v1.15.0 github.com/stretchr/testify v1.8.1 github.com/tj/go-spin v1.1.0 + go.opentelemetry.io/otel v1.12.0 + go.opentelemetry.io/otel/sdk v1.11.2 golang.org/x/sync v0.1.0 gopkg.in/yaml.v2 v2.4.0 k8s.io/api v0.26.1 @@ -55,6 +57,7 @@ require ( github.com/evanphx/json-patch/v5 v5.6.0 // indirect github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe // indirect github.com/golang-sql/sqlexp v0.1.0 // indirect + github.com/go-logr/stdr v1.2.2 // 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-20200714003250-2b9c44734f2b // indirect @@ -64,6 +67,7 @@ require ( github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sylabs/sif/v2 v2.9.0 // indirect + go.opentelemetry.io/otel/trace v1.12.0 // indirect golang.org/x/mod v0.7.0 // indirect golang.org/x/tools v0.4.0 // indirect ) @@ -189,7 +193,7 @@ require ( golang.org/x/oauth2 v0.4.0 // indirect golang.org/x/sys v0.4.0 // indirect golang.org/x/term v0.4.0 // indirect - golang.org/x/text v0.6.0 // indirect + golang.org/x/text v0.6.0 golang.org/x/time v0.3.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/api v0.107.0 // indirect diff --git a/go.sum b/go.sum index 881693960..d4ed549d6 100644 --- a/go.sum +++ b/go.sum @@ -406,8 +406,11 @@ github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KE github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= @@ -1063,6 +1066,12 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/otel v1.12.0 h1:IgfC7kqQrRccIKuB7Cl+SRUmsKbEwSGPr0Eu+/ht1SQ= +go.opentelemetry.io/otel v1.12.0/go.mod h1:geaoz0L0r1BEOR81k7/n9W4TCXYCJ7bPO7K374jQHG0= +go.opentelemetry.io/otel/sdk v1.11.2 h1:GF4JoaEx7iihdMFu30sOyRx52HDHOkl9xQ8SMqNXUiU= +go.opentelemetry.io/otel/sdk v1.11.2/go.mod h1:wZ1WxImwpq+lVRo4vsmSOxdd+xwoUJ6rqyLc3SyX9aU= +go.opentelemetry.io/otel/trace v1.12.0 h1:p28in++7Kd0r2d8gSt931O57fdjUyWxkVbESuILAeUc= +go.opentelemetry.io/otel/trace v1.12.0/go.mod h1:pHlgBynn6s25qJ2szD+Bv+iwKJttjHSI3lUAyf0GNuQ= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 h1:+FNtrFTmVw0YZGpBGX56XDee331t6JAXeK2bcyhLOOc= go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o= diff --git a/internal/traces/exporter.go b/internal/traces/exporter.go new file mode 100644 index 000000000..8f9d82714 --- /dev/null +++ b/internal/traces/exporter.go @@ -0,0 +1,273 @@ +package traces + +import ( + "context" + "sort" + "strings" + "sync" + "time" + + "github.com/replicatedhq/troubleshoot/pkg/constants" + "go.opentelemetry.io/otel/codes" + "go.opentelemetry.io/otel/sdk/trace" + "go.opentelemetry.io/otel/sdk/trace/tracetest" + "golang.org/x/text/language" + "golang.org/x/text/message" +) + +var ( + _ trace.SpanExporter = (*Exporter)(nil) + once sync.Once + exporter *Exporter + printer = message.NewPrinter(language.English) +) + +const legend = "Suceeded (S), eXcluded (X), Failed (F)\n" + +// FUTURE WORK: This exporter should only be used by troubleshoot CLIs +// until the following issue is addressed: +// 1. The cache of spans grows infinitely at the moment. This is OK for short lived +// invocations such as CLI applications running one-shot commands. For long running +// applications, this will be a problem. +// * We can drop non-troubleshoot spans from the cache. There is an OTEP to add +// "inheritable attributes" to spans which is unsupported as of today. Once/if +// it gets accepted and implemented, it will allow us to add a "troubleshoot" +// attribute to the "root" span which gets propagated to downstream spans which +// we can use to filter out non-troubleshoot spans. +// https://github.com/dynatrace-oss-contrib/oteps/blob/feature/context-scoped-attributes/text/0207-context-scoped-attributes.md +// https://github.com/open-telemetry/opentelemetry-specification/issues/1337 +// * We can "search" for the "root" span by traversing up the span tree and drop +// all spans that are not descendants of the "root" span. This can be slow, but +// we can do it in a background goroutine (adds a bit of complexity). +// 2. At the moment, the summary of an execution is the only case this exporter +// is being used for. + +// GetExporterInstance creates a singleton exporter instance +func GetExporterInstance() *Exporter { + once.Do(func() { + exporter = &Exporter{ + allSpans: make([]trace.ReadOnlySpan, 1024), + } + }) + return exporter +} + +// Exporter is an implementation of trace.SpanExporter that writes to a destination. +type Exporter struct { + spansMu sync.Mutex + allSpans []trace.ReadOnlySpan + + stoppedMu sync.RWMutex + stopped bool +} + +// ExportSpans writes spans to an in-memory cache +// This function can/will be called on every span.End() at worst. +func (e *Exporter) ExportSpans(ctx context.Context, spans []trace.ReadOnlySpan) error { + // This is a no-op if the context is canceled. + if ctx.Err() != nil { + return ctx.Err() + } + + e.stoppedMu.RLock() + stopped := e.stopped + e.stoppedMu.RUnlock() + if stopped { + return nil + } + + if len(spans) == 0 { + return nil + } + + e.spansMu.Lock() + defer e.spansMu.Unlock() + + // Cache received span updates allSpans + e.allSpans = append(e.allSpans, spans...) + + return nil +} + +func isType(stub *tracetest.SpanStub, t string) bool { + if stub == nil { + return false + } + + for _, attr := range stub.Attributes { + if string(attr.Key) == "type" && strings.Contains(attr.Value.AsString(), t) { + return true + } + } + return false +} + +func formatStubName(stub *tracetest.SpanStub) string { + if stub == nil { + return "" + } + + for _, attr := range stub.Attributes { + if stub.Status.Code == codes.Error { + return stub.Name + " (F)" + } + if string(attr.Key) == constants.EXCLUDED && attr.Value.AsBool() { + return stub.Name + " (X)" + } + } + return stub.Name + " (S)" // Assume success +} + +// maxInt returns the larger of x or y. +func maxInt(x, y int) int { + if x < y { + return y + } + return x +} + +// GetSummary returns the runtime summary of the execution +// so far. Call this function after your "root" span has ended +// and the program operations needing tracing have completed. +func (e *Exporter) GetSummary() string { + e.spansMu.Lock() + stubs := tracetest.SpanStubsFromReadOnlySpans(e.allSpans) + e.spansMu.Unlock() + + // No spans to log + if len(stubs) == 0 { + return "" + } + + // TODO: We may want to collect more information about the + // execution of the program. For example, we can collect + // the number of times a collector was executed, whether + // it was successful or not, if it was skipped, etc. + collectors := make(map[string]time.Duration) + redactors := make(map[string]time.Duration) + analysers := make(map[string]time.Duration) + + totalDuration := time.Duration(0) + + for i := range stubs { + stub := &stubs[i] + + // Summary of span stubs + duration := stub.EndTime.Sub(stub.StartTime) + stubName := formatStubName(stub) + switch { + case stub.Name == constants.TROUBLESHOOT_ROOT_SPAN_NAME: + totalDuration = duration + case isType(stub, "Collect"): + collectors[stubName] = duration + case isType(stub, "Redactors"): + redactors[stub.Name] = duration + case isType(stub, "Analyze"): + analysers[stubName] = duration + default: + continue + } + } + + sb := strings.Builder{} + + collectorsSummary(collectors, &sb) + redactorsSummary(redactors, &sb) + analysersSummary(analysers, &sb) + sb.WriteString(printer.Sprintf("\nDuration: %dms\n", totalDuration/time.Millisecond)) + + return sb.String() +} + +// summary of collector runtimes +func collectorsSummary(summary map[string]time.Duration, sb *strings.Builder) { + padding, keys := sortedKeysAndPadding(summary) + + sb.WriteString("============ Collectors summary =============\n") + sb.WriteString(legend) + sb.WriteString("=============================================\n") + if len(summary) == 0 { + sb.WriteString("No collectors executed\n") + return + } + + for _, name := range keys { + sb.WriteString(printer.Sprintf("%-*s : %dms\n", padding, name, summary[name]/time.Millisecond)) + } +} + +// summary of redactor runtime +func redactorsSummary(summary map[string]time.Duration, sb *strings.Builder) { + padding, keys := sortedKeysAndPadding(summary) + + sb.WriteString("\n============ Redactors summary =============\n") + if len(summary) == 0 { + sb.WriteString("No redactors executed\n") + return + } + + for _, name := range keys { + sb.WriteString(printer.Sprintf("%-*s : %dms\n", padding, name, summary[name]/time.Millisecond)) + } +} + +// summary of analyser runtime +func analysersSummary(summary map[string]time.Duration, sb *strings.Builder) { + padding, keys := sortedKeysAndPadding(summary) + + sb.WriteString("\n============= Analyzers summary =============\n") + sb.WriteString(legend) + sb.WriteString("=============================================\n") + if len(summary) == 0 { + sb.WriteString("No analyzers executed\n") + return + } + + for _, name := range keys { + sb.WriteString(printer.Sprintf("%-*s : %dms\n", padding, name, summary[name]/time.Millisecond)) + } +} + +func sortedKeysAndPadding(summary map[string]time.Duration) (int, []string) { + keys := make([]string, 0, len(summary)) + padding := 0 + for k := range summary { + padding = maxInt(padding, len(k)) + keys = append(keys, k) + } + sort.SliceStable(keys, func(l, r int) bool { + return summary[keys[l]] > summary[keys[r]] + }) + return padding, keys +} + +// Shutdown is called to stop the exporter, it preforms no action. +func (e *Exporter) Shutdown(ctx context.Context) error { + e.stoppedMu.Lock() + e.stopped = true + e.stoppedMu.Unlock() + + e.Reset() + + select { + case <-ctx.Done(): + return ctx.Err() + default: + } + return nil +} + +func (e *Exporter) Reset() { + e.spansMu.Lock() + e.allSpans = e.allSpans[:0] // clear the slice + e.spansMu.Unlock() +} + +// MarshalLog is the marshaling function used by the logging system to represent this exporter. +func (e *Exporter) MarshalLog() interface{} { + return struct { + Type string + }{ + Type: "troubleshoot", + } +} diff --git a/internal/traces/exporter_test.go b/internal/traces/exporter_test.go new file mode 100644 index 000000000..e7fa9ae78 --- /dev/null +++ b/internal/traces/exporter_test.go @@ -0,0 +1,187 @@ +package traces + +import ( + "context" + "fmt" + "strings" + "testing" + "time" + + "github.com/replicatedhq/troubleshoot/pkg/constants" + "github.com/replicatedhq/troubleshoot/pkg/logger" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/codes" + "go.opentelemetry.io/otel/sdk/trace" + "go.opentelemetry.io/otel/sdk/trace/tracetest" +) + +func TestExporter_GetSummary(t *testing.T) { + logger.SetQuiet(true) + + tests := []struct { + name string + spans tracetest.SpanStubs + want string + }{ + { + name: "with no spans", + spans: tracetest.SpanStubs{}, + want: "", + }, + { + name: "with root span only", + spans: tracetest.SpanStubs{ + tracetest.SpanStub{ + Name: constants.TROUBLESHOOT_ROOT_SPAN_NAME, + StartTime: time.Now(), + EndTime: time.Now().Add(time.Second), + }, + }, + want: "Duration: 1,000ms", + }, + { + name: "with collectors", + spans: tracetest.SpanStubs{ + tracetest.SpanStub{ + Name: "all-logs", StartTime: time.Now(), EndTime: time.Now().Add(time.Minute), + Attributes: []attribute.KeyValue{ + attribute.String("type", "*collect.CollectLogs"), + }, + }, + tracetest.SpanStub{ + Name: "host-os", StartTime: time.Now(), EndTime: time.Now().Add(time.Second), + Attributes: []attribute.KeyValue{ + attribute.String("type", "*collect.CollectHostOS"), + }, + }, + tracetest.SpanStub{ + Name: "excluded-collector", StartTime: time.Now(), EndTime: time.Now().Add(time.Millisecond * 2), + Attributes: []attribute.KeyValue{ + attribute.String("type", "*collect.CollectHostOS"), + attribute.Bool("excluded", true), + }, + }, + tracetest.SpanStub{ + Name: "failed-collector", StartTime: time.Now(), EndTime: time.Now().Add(time.Millisecond), + Attributes: []attribute.KeyValue{ + attribute.String("type", "*collect.CollectHostOS"), + }, + Status: trace.Status{ + Code: codes.Error, + Description: "some error", + }, + }, + }, + want: ` +============ Collectors summary ============= +Suceeded (S), eXcluded (X), Failed (F) +============================================= +all-logs (S) : 60,000ms +host-os (S) : 1,000ms +excluded-collector (X) : 2ms +failed-collector (F) : 1ms`, + }, + { + name: "with analyzers", + spans: tracetest.SpanStubs{ + tracetest.SpanStub{ + Name: "cluster-version", StartTime: time.Now(), EndTime: time.Now().Add(time.Second), + Attributes: []attribute.KeyValue{ + attribute.String("type", "*analyzer.AnalyzeClusterVersion"), + }, + }, + tracetest.SpanStub{ + Name: "host-cpu", StartTime: time.Now(), EndTime: time.Now().Add(time.Minute), + Attributes: []attribute.KeyValue{ + attribute.String("type", "*analyzer.AnalyzeHostCPU"), + }, + }, + tracetest.SpanStub{ + Name: "excluded-analyser", StartTime: time.Now(), EndTime: time.Now().Add(time.Millisecond * 2), + Attributes: []attribute.KeyValue{ + attribute.String("type", "*collect.AnalyzeHostCPU"), + attribute.Bool("excluded", true), + }, + }, + tracetest.SpanStub{ + Name: "failed-analyser", StartTime: time.Now(), EndTime: time.Now().Add(time.Millisecond), + Attributes: []attribute.KeyValue{ + attribute.String("type", "*collect.AnalyzeHostCPU"), + }, + Status: trace.Status{ + Code: codes.Error, + Description: "some error", + }, + }, + }, + want: ` +============= Analyzers summary ============= +Suceeded (S), eXcluded (X), Failed (F) +============================================= +host-cpu (S) : 60,000ms +cluster-version (S) : 1,000ms +excluded-analyser (X) : 2ms +failed-analyser (F) : 1ms`, + }, + { + name: "with redactors", + spans: tracetest.SpanStubs{ + tracetest.SpanStub{ + Name: "cluster redactor", StartTime: time.Now(), EndTime: time.Now().Add(time.Second), + Attributes: []attribute.KeyValue{ + attribute.String("type", "Redactors"), + }, + }, + }, + want: ` +============ Redactors summary ============= +cluster redactor : 1,000ms`, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + e := &Exporter{} + + ctx := context.Background() + err := e.ExportSpans(ctx, tt.spans.Snapshots()) + require.NoError(t, err) + + assert.Contains(t, e.GetSummary(), strings.TrimSpace(tt.want)) + }) + } +} + +func TestExporter_ExportSpansWithDoneContext(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + cancel() + + e := &Exporter{} + spans := tracetest.SpanStubs{} + + assert.EqualError(t, e.ExportSpans(ctx, spans.Snapshots()), context.Canceled.Error()) +} + +func TestExporter_Shutdown(t *testing.T) { + e := &Exporter{} + + ctx := context.Background() + spans := tracetest.SpanStubs{} + for i := 0; i < 5; i++ { + spans = append(spans, tracetest.SpanStub{Name: fmt.Sprintf("span-%d", i)}) + } + + err := e.ExportSpans(ctx, spans.Snapshots()) + require.NoError(t, err) + + assert.Len(t, e.allSpans, 5) + + require.NoError(t, e.Shutdown(ctx)) + assert.Len(t, e.allSpans, 0) + + err = e.ExportSpans(ctx, spans.Snapshots()) + require.NoError(t, err) + + assert.Len(t, e.allSpans, 0) +} diff --git a/internal/traces/otel.go b/internal/traces/otel.go new file mode 100644 index 000000000..01a201ea4 --- /dev/null +++ b/internal/traces/otel.go @@ -0,0 +1,60 @@ +package traces + +import ( + "context" + + "github.com/replicatedhq/troubleshoot/pkg/logger" + "github.com/replicatedhq/troubleshoot/pkg/version" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/sdk/resource" + "go.opentelemetry.io/otel/sdk/trace" + semconv "go.opentelemetry.io/otel/semconv/v1.12.0" +) + +// ConfigureTracing configures the OpenTelemetry trace provider for CLI +// commands. Projects using troubleshoot as a library would need to register +// troubleshoot's exporter like so. +// +// var tp *trace.TracerProvider // client application's trace provider +// tp.RegisterSpanProcessor( +// trace.NewSimpleSpanProcessor( +// traces.GetExporterInstance(), // Troubleshoot's exporter +// ), +// ) +// +// The client application is responsible for constructing the trace provider +// and registering the exporter. Multiple exporters can be registered. +func ConfigureTracing(processName string) (func(), error) { + r, err := resource.Merge( + resource.Default(), + resource.NewWithAttributes( + resource.Default().SchemaURL(), + semconv.ProcessCommandKey.String(processName), + semconv.ProcessRuntimeVersionKey.String(version.Version()), + attribute.String("environment", "cli"), + ), + ) + + if err != nil { + return nil, err + } + + // Trace provider for support bundle cli. Each application is required + // to have its own trace provider. + tp := trace.NewTracerProvider( + trace.WithSampler(trace.AlwaysSample()), + trace.WithSyncer( + GetExporterInstance(), + ), + trace.WithResource(r), + ) + + otel.SetTracerProvider(tp) + + return func() { + if err := tp.Shutdown(context.Background()); err != nil { + logger.Printf("Failed to shutdown trace provider: %v", err) + } + }, nil +} diff --git a/pkg/analyze/analyzer.go b/pkg/analyze/analyzer.go index 63521ec8b..bfd91d661 100644 --- a/pkg/analyze/analyzer.go +++ b/pkg/analyze/analyzer.go @@ -1,13 +1,19 @@ package analyzer import ( + "context" "fmt" "reflect" "strconv" "github.com/pkg/errors" troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" + "github.com/replicatedhq/troubleshoot/pkg/constants" + "github.com/replicatedhq/troubleshoot/pkg/logger" "github.com/replicatedhq/troubleshoot/pkg/multitype" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/codes" corev1 "k8s.io/api/core/v1" ) @@ -50,14 +56,25 @@ func isExcluded(excludeVal *multitype.BoolOrString) (bool, error) { return parsed, nil } -func HostAnalyze(hostAnalyzer *troubleshootv1beta2.HostAnalyze, getFile getCollectedFileContents, findFiles getChildCollectedFileContents) []*AnalyzeResult { +func HostAnalyze( + ctx context.Context, + hostAnalyzer *troubleshootv1beta2.HostAnalyze, + getFile getCollectedFileContents, + findFiles getChildCollectedFileContents, +) []*AnalyzeResult { analyzer, ok := GetHostAnalyzer(hostAnalyzer) if !ok { return NewAnalyzeResultError(analyzer, errors.New("invalid host analyzer")) } + _, span := otel.Tracer(constants.LIB_TRACER_NAME).Start(ctx, analyzer.Title()) + span.SetAttributes(attribute.String("type", reflect.TypeOf(analyzer).String())) + defer span.End() + isExcluded, _ := analyzer.IsExcluded() if isExcluded { + logger.Printf("Excluding %q analyzer", analyzer.Title()) + span.SetAttributes(attribute.Bool(constants.EXCLUDED, true)) return nil } @@ -83,7 +100,12 @@ func NewAnalyzeResultError(analyzer HostAnalyzer, err error) []*AnalyzeResult { }} } -func Analyze(analyzer *troubleshootv1beta2.Analyze, getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { +func Analyze( + ctx context.Context, + analyzer *troubleshootv1beta2.Analyze, + getFile getCollectedFileContents, + findFiles getChildCollectedFileContents, +) ([]*AnalyzeResult, error) { if analyzer == nil { return nil, errors.New("nil analyzer") } @@ -479,16 +501,24 @@ func Analyze(analyzer *troubleshootv1beta2.Analyze, getFile getCollectedFileCont return results, nil } + _, span := otel.Tracer(constants.LIB_TRACER_NAME).Start(ctx, analyzerInst.Title()) + span.SetAttributes(attribute.String("type", reflect.TypeOf(analyzerInst).String())) + defer span.End() + isExcluded, err := analyzerInst.IsExcluded() if err != nil { + span.SetStatus(codes.Error, err.Error()) return nil, err } if isExcluded { + logger.Printf("Excluding %q analyzer", analyzerInst.Title()) + span.SetAttributes(attribute.Bool(constants.EXCLUDED, true)) return nil, nil } results, err := analyzerInst.Analyze(getFile, findFiles) if err != nil { + span.SetStatus(codes.Error, err.Error()) return nil, err } diff --git a/pkg/analyze/analyzer_test.go b/pkg/analyze/analyzer_test.go index 0b8b4ad97..597396640 100644 --- a/pkg/analyze/analyzer_test.go +++ b/pkg/analyze/analyzer_test.go @@ -1,6 +1,7 @@ package analyzer import ( + "context" "testing" troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" @@ -67,7 +68,7 @@ func Test_GetExcludeFlag(t *testing.T) { } func TestAnalyzeWithNilAnalyzer(t *testing.T) { - got, err := Analyze(nil, nil, nil) + got, err := Analyze(context.Background(), nil, nil, nil) assert.Error(t, err) assert.Nil(t, got) } diff --git a/pkg/analyze/download.go b/pkg/analyze/download.go index 49594ac23..2f7a19f22 100644 --- a/pkg/analyze/download.go +++ b/pkg/analyze/download.go @@ -3,6 +3,7 @@ package analyzer import ( "archive/tar" "compress/gzip" + "context" "io" "io/fs" "os" @@ -24,7 +25,12 @@ type fileContentProvider struct { } // Analyze local will analyze a locally available (already downloaded) bundle -func AnalyzeLocal(localBundlePath string, analyzers []*troubleshootv1beta2.Analyze, hostAnalyzers []*troubleshootv1beta2.HostAnalyze) ([]*AnalyzeResult, error) { +func AnalyzeLocal( + ctx context.Context, + localBundlePath string, + analyzers []*troubleshootv1beta2.Analyze, + hostAnalyzers []*troubleshootv1beta2.HostAnalyze, +) ([]*AnalyzeResult, error) { rootDir, err := FindBundleRootDir(localBundlePath) if err != nil { return nil, errors.Wrap(err, "failed to find root dir") @@ -34,7 +40,7 @@ func AnalyzeLocal(localBundlePath string, analyzers []*troubleshootv1beta2.Analy analyzeResults := []*AnalyzeResult{} for _, analyzer := range analyzers { - analyzeResult, err := Analyze(analyzer, fcp.getFileContents, fcp.getChildFileContents) + analyzeResult, err := Analyze(ctx, analyzer, fcp.getFileContents, fcp.getChildFileContents) if err != nil { logger.Printf("An analyzer failed to run: %v", err) continue @@ -49,7 +55,7 @@ func AnalyzeLocal(localBundlePath string, analyzers []*troubleshootv1beta2.Analy } for _, hostAnalyzer := range hostAnalyzers { - analyzeResult := HostAnalyze(hostAnalyzer, fcp.getFileContents, fcp.getChildFileContents) + analyzeResult := HostAnalyze(ctx, hostAnalyzer, fcp.getFileContents, fcp.getChildFileContents) analyzeResults = append(analyzeResults, analyzeResult...) } @@ -81,7 +87,7 @@ func DownloadAndAnalyze(bundleURL string, analyzersSpec string) ([]*AnalyzeResul hostAnalyzers = parsedHostAnalyzers } - return AnalyzeLocal(rootDir, analyzers, hostAnalyzers) + return AnalyzeLocal(context.Background(), rootDir, analyzers, hostAnalyzers) } func DownloadAndExtractSupportBundle(bundleURL string) (string, string, error) { @@ -101,10 +107,10 @@ func DownloadAndExtractSupportBundle(bundleURL string) (string, string, error) { return "", "", errors.Wrap(err, "failed to find root dir") } - _, err = os.Stat(filepath.Join(bundleDir, constants.VersionFilename)) + _, err = os.Stat(filepath.Join(bundleDir, constants.VERSION_FILENAME)) if err != nil { os.RemoveAll(tmpDir) - return "", "", errors.Wrap(err, "failed to read "+constants.VersionFilename) + return "", "", errors.Wrap(err, "failed to read "+constants.VERSION_FILENAME) } return tmpDir, bundleDir, nil @@ -283,7 +289,7 @@ func FindBundleRootDir(localBundlePath string) (string, error) { isInSubDir := true for _, name := range names { - if name == constants.VersionFilename { + if name == constants.VERSION_FILENAME { isInSubDir = false break } diff --git a/pkg/collect/host_udpportstatus_test.go b/pkg/collect/host_udpportstatus_test.go index 569cbfe0f..32ef6a98b 100644 --- a/pkg/collect/host_udpportstatus_test.go +++ b/pkg/collect/host_udpportstatus_test.go @@ -29,13 +29,9 @@ func TestCollectHostUDPPortStatus_Collect(t *testing.T) { return port, conn, err } - type fields struct { - hostCollector *troubleshootv1beta2.UDPPortStatus - } tests := []struct { name string getPort func(t *testing.T) (port int, closeFn func() error) - fields fields want map[string][]byte }{ { diff --git a/pkg/constants/constants.go b/pkg/constants/constants.go index 40f1781ba..494119f71 100644 --- a/pkg/constants/constants.go +++ b/pkg/constants/constants.go @@ -9,11 +9,17 @@ const ( DEFAULT_CLIENT_BURST = 100 // DEFAULT_CLIENT_USER_AGENT is an field that specifies the caller of troubleshoot request. DEFAULT_CLIENT_USER_AGENT = "ReplicatedTroubleshoot" - // VersionFilename is the name of the file that contains the support bundle version. - VersionFilename = "version.yaml" + // VERSION_FILENAME is the name of the file that contains the support bundle version. + VERSION_FILENAME = "version.yaml" // DEFAULT_LOGS_COLLECTOR_TIMEOUT is the default timeout for logs collector. DEFAULT_LOGS_COLLECTOR_TIMEOUT = 60 * time.Second + // Tracing constants + + LIB_TRACER_NAME = "github.com/replicatedhq/troubleshoot" + TROUBLESHOOT_ROOT_SPAN_NAME = "ReplicatedTroubleshootRootSpan" + EXCLUDED = "excluded" + // Cluster Resources Collector Directories CLUSTER_RESOURCES_DIR = "cluster-resources" CLUSTER_RESOURCES_NAMESPACES = "namespace" diff --git a/pkg/preflight/analyze.go b/pkg/preflight/analyze.go index 246b3fbc0..9edb5bc34 100644 --- a/pkg/preflight/analyze.go +++ b/pkg/preflight/analyze.go @@ -1,6 +1,7 @@ package preflight import ( + "context" "encoding/json" "fmt" "path/filepath" @@ -13,12 +14,12 @@ import ( // Analyze runs the analyze phase of preflight checks func (c ClusterCollectResult) Analyze() []*analyze.AnalyzeResult { - return doAnalyze(c.AllCollectedData, c.Spec.Spec.Analyzers, nil, "") + return doAnalyze(c.Context, c.AllCollectedData, c.Spec.Spec.Analyzers, nil, "") } // Analyze runs the analyze phase of host preflight checks func (c HostCollectResult) Analyze() []*analyze.AnalyzeResult { - return doAnalyze(c.AllCollectedData, nil, c.Spec.Spec.Analyzers, "") + return doAnalyze(c.Context, c.AllCollectedData, nil, c.Spec.Spec.Analyzers, "") } // Analyze runs the analyze phase of host preflight checks. @@ -43,12 +44,18 @@ func (c RemoteCollectResult) Analyze() []*analyze.AnalyzeResult { byteResult[k] = []byte(v) } - results = append(results, doAnalyze(byteResult, nil, c.Spec.Spec.Analyzers, nodeName)...) + results = append(results, doAnalyze(c.Context, byteResult, nil, c.Spec.Spec.Analyzers, nodeName)...) } return results } -func doAnalyze(allCollectedData map[string][]byte, analyzers []*troubleshootv1beta2.Analyze, hostAnalyzers []*troubleshootv1beta2.HostAnalyze, nodeName string) []*analyze.AnalyzeResult { +func doAnalyze( + ctx context.Context, + allCollectedData map[string][]byte, + analyzers []*troubleshootv1beta2.Analyze, + hostAnalyzers []*troubleshootv1beta2.HostAnalyze, + nodeName string, +) []*analyze.AnalyzeResult { getCollectedFileContents := func(fileName string) ([]byte, error) { contents, ok := allCollectedData[fileName] if !ok { @@ -89,7 +96,7 @@ func doAnalyze(allCollectedData map[string][]byte, analyzers []*troubleshootv1be analyzeResults := []*analyze.AnalyzeResult{} for _, analyzer := range analyzers { - analyzeResult, err := analyze.Analyze(analyzer, getCollectedFileContents, getChildCollectedFileContents) + analyzeResult, err := analyze.Analyze(ctx, analyzer, getCollectedFileContents, getChildCollectedFileContents) if err != nil { strict, strictErr := HasStrictAnalyzer(analyzer) if strictErr != nil { @@ -112,7 +119,7 @@ func doAnalyze(allCollectedData map[string][]byte, analyzers []*troubleshootv1be } for _, hostAnalyzer := range hostAnalyzers { - analyzeResult := analyze.HostAnalyze(hostAnalyzer, getCollectedFileContents, getChildCollectedFileContents) + analyzeResult := analyze.HostAnalyze(ctx, hostAnalyzer, getCollectedFileContents, getChildCollectedFileContents) analyzeResults = append(analyzeResults, analyzeResult...) } diff --git a/pkg/preflight/collect.go b/pkg/preflight/collect.go index 7cf174d88..fbcbbc1eb 100644 --- a/pkg/preflight/collect.go +++ b/pkg/preflight/collect.go @@ -12,7 +12,11 @@ import ( troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" "github.com/replicatedhq/troubleshoot/pkg/collect" "github.com/replicatedhq/troubleshoot/pkg/constants" + "github.com/replicatedhq/troubleshoot/pkg/logger" "github.com/replicatedhq/troubleshoot/pkg/version" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/codes" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" ) @@ -55,6 +59,7 @@ type ClusterCollectResult struct { RemoteCollectors collect.RemoteCollectors isRBACAllowed bool Spec *troubleshootv1beta2.Preflight + Context context.Context } func (cr ClusterCollectResult) IsRBACAllowed() bool { @@ -65,6 +70,7 @@ type HostCollectResult struct { AllCollectedData map[string][]byte Collectors []collect.HostCollector Spec *troubleshootv1beta2.HostPreflight + Context context.Context } func (cr HostCollectResult) IsRBACAllowed() bool { @@ -75,6 +81,7 @@ type RemoteCollectResult struct { AllCollectedData map[string][]byte Collectors collect.RemoteCollectors Spec *troubleshootv1beta2.HostPreflight + Context context.Context } func (cr RemoteCollectResult) IsRBACAllowed() bool { @@ -83,6 +90,12 @@ func (cr RemoteCollectResult) IsRBACAllowed() bool { // CollectHost runs the collection phase of host preflight checks func CollectHost(opts CollectOpts, p *troubleshootv1beta2.HostPreflight) (CollectResult, error) { + return CollectHostWithContext(context.Background(), opts, p) +} + +func CollectHostWithContext( + ctx context.Context, opts CollectOpts, p *troubleshootv1beta2.HostPreflight, +) (CollectResult, error) { collectSpecs := make([]*troubleshootv1beta2.HostCollect, 0, 0) if p != nil && p.Spec.Collectors != nil { collectSpecs = append(collectSpecs, p.Spec.Collectors...) @@ -101,11 +114,18 @@ func CollectHost(opts CollectOpts, p *troubleshootv1beta2.HostPreflight) (Collec collectResult := HostCollectResult{ Collectors: collectors, Spec: p, + Context: ctx, } for _, collector := range collectors { + _, span := otel.Tracer(constants.LIB_TRACER_NAME).Start(ctx, collector.Title()) + span.SetAttributes(attribute.String("type", reflect.TypeOf(collector).String())) + isExcluded, _ := collector.IsExcluded() if isExcluded { + logger.Printf("Excluding %q collector", collector.Title()) + span.SetAttributes(attribute.Bool(constants.EXCLUDED, true)) + span.End() continue } @@ -117,6 +137,7 @@ func CollectHost(opts CollectOpts, p *troubleshootv1beta2.HostPreflight) (Collec for k, v := range result { allCollectedData[k] = v } + span.End() } collectResult.AllCollectedData = allCollectedData @@ -126,6 +147,10 @@ func CollectHost(opts CollectOpts, p *troubleshootv1beta2.HostPreflight) (Collec // Collect runs the collection phase of preflight checks func Collect(opts CollectOpts, p *troubleshootv1beta2.Preflight) (CollectResult, error) { + return CollectWithContext(context.Background(), opts, p) +} + +func CollectWithContext(ctx context.Context, opts CollectOpts, p *troubleshootv1beta2.Preflight) (CollectResult, error) { var allCollectors []collect.Collector var foundForbidden bool @@ -133,8 +158,12 @@ func Collect(opts CollectOpts, p *troubleshootv1beta2.Preflight) (CollectResult, if p != nil && p.Spec.Collectors != nil { collectSpecs = append(collectSpecs, p.Spec.Collectors...) } - collectSpecs = collect.EnsureCollectorInList(collectSpecs, troubleshootv1beta2.Collect{ClusterInfo: &troubleshootv1beta2.ClusterInfo{}}) - collectSpecs = collect.EnsureCollectorInList(collectSpecs, troubleshootv1beta2.Collect{ClusterResources: &troubleshootv1beta2.ClusterResources{}}) + collectSpecs = collect.EnsureCollectorInList( + collectSpecs, troubleshootv1beta2.Collect{ClusterInfo: &troubleshootv1beta2.ClusterInfo{}}, + ) + collectSpecs = collect.EnsureCollectorInList( + collectSpecs, troubleshootv1beta2.Collect{ClusterResources: &troubleshootv1beta2.ClusterResources{}}, + ) collectSpecs = collect.DedupCollectors(collectSpecs) collectSpecs = collect.EnsureClusterResourcesFirst(collectSpecs) @@ -153,7 +182,7 @@ func Collect(opts CollectOpts, p *troubleshootv1beta2.Preflight) (CollectResult, for _, desiredCollector := range collectSpecs { if collectorInterface, ok := collect.GetCollector(desiredCollector, "", opts.Namespace, opts.KubernetesRestConfig, k8sClient, nil); ok { if collector, ok := collectorInterface.(collect.Collector); ok { - err := collector.CheckRBAC(context.Background(), collector, desiredCollector, opts.KubernetesRestConfig, opts.Namespace) + err := collector.CheckRBAC(ctx, collector, desiredCollector, opts.KubernetesRestConfig, opts.Namespace) if err != nil { return nil, errors.Wrap(err, "failed to check RBAC for collectors") } @@ -193,6 +222,7 @@ func Collect(opts CollectOpts, p *troubleshootv1beta2.Preflight) (CollectResult, collectResult := ClusterCollectResult{ Collectors: allCollectors, Spec: p, + Context: ctx, } if foundForbidden && !opts.IgnorePermissionErrors { @@ -201,8 +231,14 @@ func Collect(opts CollectOpts, p *troubleshootv1beta2.Preflight) (CollectResult, } for i, collector := range allCollectors { + _, span := otel.Tracer(constants.LIB_TRACER_NAME).Start(ctx, collector.Title()) + span.SetAttributes(attribute.String("type", reflect.TypeOf(collector).String())) + isExcluded, _ := collector.IsExcluded() if isExcluded { + logger.Printf("Excluding %q collector", collector.Title()) + span.SetAttributes(attribute.Bool(constants.EXCLUDED, true)) + span.End() continue } @@ -217,6 +253,8 @@ func Collect(opts CollectOpts, p *troubleshootv1beta2.Preflight) (CollectResult, TotalCount: len(allCollectors), Collectors: collectorList, } + span.SetStatus(codes.Error, "skipping collector, insufficient RBAC permissions") + span.End() continue } } @@ -245,6 +283,8 @@ func Collect(opts CollectOpts, p *troubleshootv1beta2.Preflight) (CollectResult, TotalCount: len(allCollectors), Collectors: collectorList, } + span.SetStatus(codes.Error, err.Error()) + span.End() continue } @@ -262,6 +302,7 @@ func Collect(opts CollectOpts, p *troubleshootv1beta2.Preflight) (CollectResult, for k, v := range result { allCollectedData[k] = v } + span.End() } collectResult.AllCollectedData = allCollectedData @@ -271,6 +312,10 @@ func Collect(opts CollectOpts, p *troubleshootv1beta2.Preflight) (CollectResult, // Collect runs the collection phase of preflight checks func CollectRemote(opts CollectOpts, p *troubleshootv1beta2.HostPreflight) (CollectResult, error) { + return CollectRemoteWithContext(context.Background(), opts, p) +} + +func CollectRemoteWithContext(ctx context.Context, opts CollectOpts, p *troubleshootv1beta2.HostPreflight) (CollectResult, error) { collectSpecs := make([]*troubleshootv1beta2.RemoteCollect, 0, 0) if p != nil && p.Spec.RemoteCollectors != nil { collectSpecs = append(collectSpecs, p.Spec.RemoteCollectors...) @@ -296,6 +341,7 @@ func CollectRemote(opts CollectOpts, p *troubleshootv1beta2.HostPreflight) (Coll collectResult := RemoteCollectResult{ Collectors: collectors, Spec: p, + Context: ctx, } // generate a map of all collectors for atomic status messages @@ -308,6 +354,9 @@ func CollectRemote(opts CollectOpts, p *troubleshootv1beta2.HostPreflight) (Coll // Run preflights collectors synchronously for i, collector := range collectors { + _, span := otel.Tracer(constants.LIB_TRACER_NAME).Start(ctx, collector.GetDisplayName()) + span.SetAttributes(attribute.String("type", reflect.TypeOf(collector).String())) + collectorList[collector.GetDisplayName()] = CollectorStatus{ Status: "running", } @@ -334,6 +383,8 @@ func CollectRemote(opts CollectOpts, p *troubleshootv1beta2.HostPreflight) (Coll TotalCount: len(collectors), Collectors: collectorList, } + span.SetStatus(codes.Error, err.Error()) + span.End() continue } @@ -375,6 +426,8 @@ func CollectRemote(opts CollectOpts, p *troubleshootv1beta2.HostPreflight) (Coll } } + + span.End() } collectResult.AllCollectedData = allCollectedData diff --git a/pkg/preflight/run.go b/pkg/preflight/run.go index 9cb246db2..9a0dd50fd 100644 --- a/pkg/preflight/run.go +++ b/pkg/preflight/run.go @@ -3,7 +3,7 @@ package preflight import ( "context" "fmt" - "io/ioutil" + "io" "net/http" "net/url" "os" @@ -18,12 +18,14 @@ import ( analyzer "github.com/replicatedhq/troubleshoot/pkg/analyze" troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" troubleshootclientsetscheme "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/scheme" + "github.com/replicatedhq/troubleshoot/pkg/constants" "github.com/replicatedhq/troubleshoot/pkg/docrewrite" "github.com/replicatedhq/troubleshoot/pkg/k8sutil" "github.com/replicatedhq/troubleshoot/pkg/oci" "github.com/replicatedhq/troubleshoot/pkg/specs" "github.com/spf13/viper" spin "github.com/tj/go-spin" + "go.opentelemetry.io/otel" "golang.org/x/sync/errgroup" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" @@ -31,6 +33,10 @@ import ( ) func RunPreflights(interactive bool, output string, format string, args []string) error { + ctx, root := otel.Tracer( + constants.LIB_TRACER_NAME).Start(context.Background(), constants.TROUBLESHOOT_ROOT_SPAN_NAME) + defer root.End() + if interactive { fmt.Print(cursor.Hide()) defer fmt.Print(cursor.Show()) @@ -64,7 +70,7 @@ func RunPreflights(interactive bool, output string, format string, args []string preflightContent = spec } else if _, err = os.Stat(v); err == nil { - b, err := ioutil.ReadFile(v) + b, err := os.ReadFile(v) if err != nil { return err } @@ -103,7 +109,7 @@ func RunPreflights(interactive bool, output string, format string, args []string } defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) if err != nil { return err } @@ -142,7 +148,7 @@ func RunPreflights(interactive bool, output string, format string, args []string progressCh := make(chan interface{}) defer close(progressCh) - ctx, stopProgressCollection := context.WithCancel(context.Background()) + ctx, stopProgressCollection := context.WithCancel(ctx) // make sure we shut down progress collection goroutines if an error occurs defer stopProgressCollection() progressCollection, ctx := errgroup.WithContext(ctx) @@ -156,7 +162,7 @@ func RunPreflights(interactive bool, output string, format string, args []string uploadResultsMap := make(map[string][]CollectResult) if preflightSpec != nil { - r, err := collectInCluster(preflightSpec, progressCh) + r, err := collectInCluster(ctx, preflightSpec, progressCh) if err != nil { return errors.Wrap(err, "failed to collect in cluster") } @@ -165,7 +171,7 @@ func RunPreflights(interactive bool, output string, format string, args []string } if uploadResultSpecs != nil { for _, spec := range uploadResultSpecs { - r, err := collectInCluster(spec, progressCh) + r, err := collectInCluster(ctx, spec, progressCh) if err != nil { return errors.Wrap(err, "failed to collect in cluster") } @@ -176,14 +182,14 @@ func RunPreflights(interactive bool, output string, format string, args []string } if hostPreflightSpec != nil { if len(hostPreflightSpec.Spec.Collectors) > 0 { - r, err := collectHost(hostPreflightSpec, progressCh) + r, err := collectHost(ctx, hostPreflightSpec, progressCh) if err != nil { return errors.Wrap(err, "failed to collect from host") } collectResults = append(collectResults, *r) } if len(hostPreflightSpec.Spec.RemoteCollectors) > 0 { - r, err := collectRemote(hostPreflightSpec, progressCh) + r, err := collectRemote(ctx, hostPreflightSpec, progressCh) if err != nil { return errors.Wrap(err, "failed to collect remotely") } @@ -284,7 +290,7 @@ func collectNonInteractiveProgess(ctx context.Context, progressCh <-chan interfa } } -func collectInCluster(preflightSpec *troubleshootv1beta2.Preflight, progressCh chan interface{}) (*CollectResult, error) { +func collectInCluster(ctx context.Context, preflightSpec *troubleshootv1beta2.Preflight, progressCh chan interface{}) (*CollectResult, error) { v := viper.GetViper() restConfig, err := k8sutil.GetRESTConfig() @@ -306,7 +312,7 @@ func collectInCluster(preflightSpec *troubleshootv1beta2.Preflight, progressCh c } } - collectResults, err := Collect(collectOpts, preflightSpec) + collectResults, err := CollectWithContext(ctx, collectOpts, preflightSpec) if err != nil { if collectResults != nil && !collectResults.IsRBACAllowed() { if preflightSpec.Spec.UploadResultsTo != "" { @@ -323,7 +329,7 @@ func collectInCluster(preflightSpec *troubleshootv1beta2.Preflight, progressCh c return &collectResults, nil } -func collectRemote(preflightSpec *troubleshootv1beta2.HostPreflight, progressCh chan interface{}) (*CollectResult, error) { +func collectRemote(ctx context.Context, preflightSpec *troubleshootv1beta2.HostPreflight, progressCh chan interface{}) (*CollectResult, error) { v := viper.GetViper() restConfig, err := k8sutil.GetRESTConfig() @@ -365,7 +371,7 @@ func collectRemote(preflightSpec *troubleshootv1beta2.HostPreflight, progressCh return &collectResults, nil } -func collectHost(hostPreflightSpec *troubleshootv1beta2.HostPreflight, progressCh chan interface{}) (*CollectResult, error) { +func collectHost(ctx context.Context, hostPreflightSpec *troubleshootv1beta2.HostPreflight, progressCh chan interface{}) (*CollectResult, error) { collectOpts := CollectOpts{ ProgressChan: progressCh, } diff --git a/pkg/supportbundle/collect.go b/pkg/supportbundle/collect.go index 63c0adcc7..9971aa6e7 100644 --- a/pkg/supportbundle/collect.go +++ b/pkg/supportbundle/collect.go @@ -15,13 +15,17 @@ import ( "github.com/replicatedhq/troubleshoot/pkg/collect" "github.com/replicatedhq/troubleshoot/pkg/constants" "github.com/replicatedhq/troubleshoot/pkg/convert" + "github.com/replicatedhq/troubleshoot/pkg/logger" "github.com/replicatedhq/troubleshoot/pkg/version" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/codes" "gopkg.in/yaml.v2" "k8s.io/client-go/kubernetes" ) -func runHostCollectors(hostCollectors []*troubleshootv1beta2.HostCollect, additionalRedactors *troubleshootv1beta2.Redactor, bundlePath string, opts SupportBundleCreateOpts) (collect.CollectorResult, error) { - collectSpecs := make([]*troubleshootv1beta2.HostCollect, 0, 0) +func runHostCollectors(ctx context.Context, hostCollectors []*troubleshootv1beta2.HostCollect, additionalRedactors *troubleshootv1beta2.Redactor, bundlePath string, opts SupportBundleCreateOpts) (collect.CollectorResult, error) { + collectSpecs := make([]*troubleshootv1beta2.HostCollect, 0) collectSpecs = append(collectSpecs, hostCollectors...) allCollectedData := make(map[string][]byte) @@ -35,16 +39,25 @@ func runHostCollectors(hostCollectors []*troubleshootv1beta2.HostCollect, additi } for _, collector := range collectors { + // TODO: Add context to host collectors + _, span := otel.Tracer(constants.LIB_TRACER_NAME).Start(ctx, collector.Title()) + span.SetAttributes(attribute.String("type", reflect.TypeOf(collector).String())) + isExcluded, _ := collector.IsExcluded() if isExcluded { + logger.Printf("Excluding %q collector", collector.Title()) + span.SetAttributes(attribute.Bool(constants.EXCLUDED, true)) + span.End() continue } opts.ProgressChan <- fmt.Sprintf("[%s] Running host collector...", collector.Title()) result, err := collector.Collect(opts.ProgressChan) if err != nil { + span.SetStatus(codes.Error, err.Error()) opts.ProgressChan <- errors.Errorf("failed to run host collector: %s: %v", collector.Title(), err) } + span.End() for k, v := range result { allCollectedData[k] = v } @@ -58,17 +71,21 @@ func runHostCollectors(hostCollectors []*troubleshootv1beta2.HostCollect, additi } if opts.Redact { + _, span := otel.Tracer(constants.LIB_TRACER_NAME).Start(ctx, "Host collectors") + span.SetAttributes(attribute.String("type", "Redactors")) err := collect.RedactResult(bundlePath, collectResult, globalRedactors) if err != nil { err = errors.Wrap(err, "failed to redact host collector results") + span.SetStatus(codes.Error, err.Error()) return collectResult, err } + span.End() } return collectResult, nil } -func runCollectors(collectors []*troubleshootv1beta2.Collect, additionalRedactors *troubleshootv1beta2.Redactor, bundlePath string, opts SupportBundleCreateOpts) (collect.CollectorResult, error) { +func runCollectors(ctx context.Context, collectors []*troubleshootv1beta2.Collect, additionalRedactors *troubleshootv1beta2.Redactor, bundlePath string, opts SupportBundleCreateOpts) (collect.CollectorResult, error) { var allCollectors []collect.Collector var foundForbidden bool @@ -94,7 +111,7 @@ func runCollectors(collectors []*troubleshootv1beta2.Collect, additionalRedactor for _, desiredCollector := range collectSpecs { if collectorInterface, ok := collect.GetCollector(desiredCollector, bundlePath, opts.Namespace, opts.KubernetesRestConfig, k8sClient, opts.SinceTime); ok { if collector, ok := collectorInterface.(collect.Collector); ok { - err := collector.CheckRBAC(context.Background(), collector, desiredCollector, opts.KubernetesRestConfig, opts.Namespace) + err := collector.CheckRBAC(ctx, collector, desiredCollector, opts.KubernetesRestConfig, opts.Namespace) if err != nil { return nil, errors.Wrap(err, "failed to check RBAC for collectors") } @@ -130,8 +147,14 @@ func runCollectors(collectors []*troubleshootv1beta2.Collect, additionalRedactor } for _, collector := range allCollectors { + _, span := otel.Tracer(constants.LIB_TRACER_NAME).Start(ctx, collector.Title()) + span.SetAttributes(attribute.String("type", reflect.TypeOf(collector).String())) + isExcluded, _ := collector.IsExcluded() if isExcluded { + logger.Printf("Excluding %q collector", collector.Title()) + span.SetAttributes(attribute.Bool(constants.EXCLUDED, true)) + span.End() continue } @@ -140,17 +163,22 @@ func runCollectors(collectors []*troubleshootv1beta2.Collect, additionalRedactor if _, ok := collector.(*collect.CollectClusterResources); !ok { msg := fmt.Sprintf("skipping collector %s with insufficient RBAC permissions", collector.Title()) opts.CollectorProgressCallback(opts.ProgressChan, msg) + span.SetStatus(codes.Error, "skipping collector, insufficient RBAC permissions") + span.End() continue } } opts.CollectorProgressCallback(opts.ProgressChan, collector.Title()) result, err := collector.Collect(opts.ProgressChan) if err != nil { + span.SetStatus(codes.Error, err.Error()) opts.ProgressChan <- errors.Errorf("failed to run collector: %s: %v", collector.Title(), err) } + for k, v := range result { allCollectedData[k] = v } + span.End() } collectResult := allCollectedData @@ -161,10 +189,17 @@ func runCollectors(collectors []*troubleshootv1beta2.Collect, additionalRedactor } if opts.Redact { + // TODO: Should we record how long each redactor takes? + _, span := otel.Tracer(constants.LIB_TRACER_NAME).Start(ctx, "In-cluster collectors") + span.SetAttributes(attribute.String("type", "Redactors")) err := collect.RedactResult(bundlePath, collectResult, globalRedactors) if err != nil { - return collectResult, errors.Wrap(err, "failed to redact in cluster collector results") + err := errors.Wrap(err, "failed to redact in cluster collector results") + span.SetStatus(codes.Error, err.Error()) + span.End() + return collectResult, err } + span.End() } return collectResult, nil diff --git a/pkg/supportbundle/supportbundle.go b/pkg/supportbundle/supportbundle.go index 8cbe1dfc6..e68eb7c72 100644 --- a/pkg/supportbundle/supportbundle.go +++ b/pkg/supportbundle/supportbundle.go @@ -1,6 +1,8 @@ package supportbundle import ( + "bytes" + "context" "fmt" "net/http" "os" @@ -11,11 +13,14 @@ import ( cursor "github.com/ahmetalpbalkan/go-cursor" "github.com/fatih/color" "github.com/pkg/errors" + "github.com/replicatedhq/troubleshoot/internal/traces" analyzer "github.com/replicatedhq/troubleshoot/pkg/analyze" troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" "github.com/replicatedhq/troubleshoot/pkg/collect" "github.com/replicatedhq/troubleshoot/pkg/constants" "github.com/replicatedhq/troubleshoot/pkg/convert" + "github.com/replicatedhq/troubleshoot/pkg/logger" + "go.opentelemetry.io/otel" "k8s.io/client-go/rest" "k8s.io/klog/v2" ) @@ -43,7 +48,10 @@ type SupportBundleResponse struct { // collectors, analyzers and after collection steps. Input arguments are specifications. // if FromCLI option is set to true, the output is the name of the archive on disk in the cwd. // if FromCLI option is set to false, the support bundle is archived in the OS temp folder (os.TempDir()). -func CollectSupportBundleFromSpec(spec *troubleshootv1beta2.SupportBundleSpec, additionalRedactors *troubleshootv1beta2.Redactor, opts SupportBundleCreateOpts) (*SupportBundleResponse, error) { +func CollectSupportBundleFromSpec( + spec *troubleshootv1beta2.SupportBundleSpec, additionalRedactors *troubleshootv1beta2.Redactor, opts SupportBundleCreateOpts, +) (*SupportBundleResponse, error) { + resultsResponse := SupportBundleResponse{} if opts.KubernetesRestConfig == nil { @@ -90,13 +98,23 @@ func CollectSupportBundleFromSpec(spec *troubleshootv1beta2.SupportBundleSpec, a var result, files, hostFiles collect.CollectorResult + ctx, root := otel.Tracer(constants.LIB_TRACER_NAME).Start( + context.Background(), constants.TROUBLESHOOT_ROOT_SPAN_NAME, + ) + defer func() { + // If this function returns an error, root.End() may not be called. + // We want to ensure this happens, so we defer it. It is safe to call + // root.End() multiple times. + root.End() + }() + // Cache error returned by collectors and return it at the end of the function // so as to have a chance to run analyzers and archive the support bundle after. // If both host and in cluster collectors fail, the errors will be wrapped collectorsErrs := []string{} if spec.HostCollectors != nil { // Run host collectors - hostFiles, err = runHostCollectors(spec.HostCollectors, additionalRedactors, bundlePath, opts) + hostFiles, err = runHostCollectors(ctx, spec.HostCollectors, additionalRedactors, bundlePath, opts) if err != nil { collectorsErrs = append(collectorsErrs, fmt.Sprintf("failed to run host collectors: %s", err)) } @@ -104,7 +122,7 @@ func CollectSupportBundleFromSpec(spec *troubleshootv1beta2.SupportBundleSpec, a if spec.Collectors != nil { // Run collectors - files, err = runCollectors(spec.Collectors, additionalRedactors, bundlePath, opts) + files, err = runCollectors(ctx, spec.Collectors, additionalRedactors, bundlePath, opts) if err != nil { collectorsErrs = append(collectorsErrs, fmt.Sprintf("failed to run collectors: %s", err)) } @@ -128,13 +146,13 @@ func CollectSupportBundleFromSpec(spec *troubleshootv1beta2.SupportBundleSpec, a return nil, errors.Wrap(err, "failed to get version file") } - err = result.SaveResult(bundlePath, constants.VersionFilename, version) + err = result.SaveResult(bundlePath, constants.VERSION_FILENAME, version) if err != nil { return nil, errors.Wrap(err, "failed to write version") } // Run Analyzers - analyzeResults, err := AnalyzeSupportBundle(spec, bundlePath) + analyzeResults, err := AnalyzeSupportBundle(ctx, spec, bundlePath) if err != nil { if opts.FromCLI { c := color.New(color.FgHiRed) @@ -156,6 +174,17 @@ func CollectSupportBundleFromSpec(spec *troubleshootv1beta2.SupportBundleSpec, a return nil, errors.Wrap(err, "failed to write analysis") } + // Complete tracing by ending the root span and collecting + // the summary of the traces. Store them in the support bundle. + root.End() + summary := traces.GetExporterInstance().GetSummary() + err = result.SaveResult(bundlePath, "execution-data/summary.txt", bytes.NewReader([]byte(summary))) + if err != nil { + // Don't fail the support bundle if we can't save the execution summary + logger.Printf("failed to save execution summary file in the support bundle: %v", err) + } + + // Archive Support Bundle if err := result.ArchiveSupportBundle(bundlePath, filename); err != nil { return nil, errors.Wrap(err, "create bundle file") } @@ -174,6 +203,7 @@ func CollectSupportBundleFromSpec(spec *troubleshootv1beta2.SupportBundleSpec, a if len(collectorsErrs) > 0 { // TODO: Consider a collectors error type + // TODO: use errors.Join in go 1.20 (https://pkg.go.dev/errors#Join) return &resultsResponse, fmt.Errorf(strings.Join(collectorsErrs, "\n")) } @@ -222,11 +252,11 @@ func ProcessSupportBundleAfterCollection(spec *troubleshootv1beta2.SupportBundle // AnalyzeSupportBundle performs analysis on a support bundle using the support bundle spec and an already unpacked support // bundle on disk -func AnalyzeSupportBundle(spec *troubleshootv1beta2.SupportBundleSpec, tmpDir string) ([]*analyzer.AnalyzeResult, error) { +func AnalyzeSupportBundle(ctx context.Context, spec *troubleshootv1beta2.SupportBundleSpec, tmpDir string) ([]*analyzer.AnalyzeResult, error) { if len(spec.Analyzers) == 0 && len(spec.HostAnalyzers) == 0 { return nil, nil } - analyzeResults, err := analyzer.AnalyzeLocal(tmpDir, spec.Analyzers, spec.HostAnalyzers) + analyzeResults, err := analyzer.AnalyzeLocal(ctx, tmpDir, spec.Analyzers, spec.HostAnalyzers) if err != nil { return nil, errors.Wrap(err, "failed to analyze support bundle") } From c8f883c73b5852b6b0baa8b9ab0ce90ca09eebb7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Feb 2023 09:59:37 +0000 Subject: [PATCH 22/55] 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> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 36fca2eab..ee30b561d 100644 --- a/go.mod +++ b/go.mod @@ -46,7 +46,7 @@ require ( k8s.io/client-go v0.26.1 k8s.io/klog/v2 v2.90.0 oras.land/oras-go v1.2.2 - sigs.k8s.io/controller-runtime v0.14.2 + sigs.k8s.io/controller-runtime v0.14.4 ) require ( diff --git a/go.sum b/go.sum index d4ed549d6..03e1e4856 100644 --- a/go.sum +++ b/go.sum @@ -1644,8 +1644,8 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= -sigs.k8s.io/controller-runtime v0.14.2 h1:P6IwDhbsRWsBClt/8/h8Zy36bCuGuW5Op7MHpFrN/60= -sigs.k8s.io/controller-runtime v0.14.2/go.mod h1:WqIdsAY6JBsjfc/CqO0CORmNtoCtE4S6qbPc9s68h+0= +sigs.k8s.io/controller-runtime v0.14.4 h1:Kd/Qgx5pd2XUL08eOV2vwIq3L9GhIbJ5Nxengbd4/0M= +sigs.k8s.io/controller-runtime v0.14.4/go.mod h1:WqIdsAY6JBsjfc/CqO0CORmNtoCtE4S6qbPc9s68h+0= sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k= sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/kustomize/api v0.12.1 h1:7YM7gW3kYBwtKvoY216ZzY+8hM+lV53LUayghNRJ0vM= From 8087953daf4d523dd59c3470bb4ee6a716227fa7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Feb 2023 10:00:45 +0000 Subject: [PATCH 23/55] 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> --- go.mod | 2 +- go.sum | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index ee30b561d..83f68291a 100644 --- a/go.mod +++ b/go.mod @@ -27,7 +27,7 @@ require ( github.com/pkg/errors v0.9.1 github.com/replicatedhq/termui/v3 v3.1.1-0.20200811145416-f40076d26851 github.com/segmentio/ksuid v1.0.4 - github.com/shirou/gopsutil/v3 v3.22.12 + github.com/shirou/gopsutil/v3 v3.23.1 github.com/sirupsen/logrus v1.9.0 github.com/spf13/cobra v1.6.1 github.com/spf13/pflag v1.0.5 diff --git a/go.sum b/go.sum index 03e1e4856..d9c37259f 100644 --- a/go.sum +++ b/go.sum @@ -929,8 +929,8 @@ github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c= github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= -github.com/shirou/gopsutil/v3 v3.22.12 h1:oG0ns6poeUSxf78JtOsfygNWuEHYYz8hnnNg7P04TJs= -github.com/shirou/gopsutil/v3 v3.22.12/go.mod h1:Xd7P1kwZcp5VW52+9XsirIKd/BROzbb2wdX3Kqlz9uI= +github.com/shirou/gopsutil/v3 v3.23.1 h1:a9KKO+kGLKEvcPIs4W62v0nu3sciVDOOOPUD0Hz7z/4= +github.com/shirou/gopsutil/v3 v3.23.1/go.mod h1:NN6mnm5/0k8jw4cBfCnJtr5L7ErOTg18tMNpgFkn0hA= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= @@ -1324,7 +1324,6 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= From 5946e2f0ab72d0a06c57ff512ff3b71f13c642fe Mon Sep 17 00:00:00 2001 From: Tom Wieczorek Date: Fri, 10 Feb 2023 18:25:57 +0100 Subject: [PATCH 24/55] chore: Don't hardcode /bin/bash (#1011) Bash is not always installed in /bin/bash. Mitigate that by relying on bash being in PATH. --- Makefile | 2 +- scripts/host-preflight-integration-test.sh | 2 +- scripts/initialize-sbom-build.sh | 2 +- test/validate-preflight-e2e.sh | 2 +- test/validate-support-bundle-e2e.sh | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index e472bf82f..b99370d4b 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ # Image URL to use all building/pushing image targets IMG ?= controller:latest -SHELL := /bin/bash -o pipefail +SHELL := bash -o pipefail VERSION_PACKAGE = github.com/replicatedhq/troubleshoot/pkg/version VERSION ?=`git describe --tags --dirty` DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` diff --git a/scripts/host-preflight-integration-test.sh b/scripts/host-preflight-integration-test.sh index 513a4ad7f..be4069fa9 100755 --- a/scripts/host-preflight-integration-test.sh +++ b/scripts/host-preflight-integration-test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash function say() { echo diff --git a/scripts/initialize-sbom-build.sh b/scripts/initialize-sbom-build.sh index 34b2759d5..4c96c9a3c 100755 --- a/scripts/initialize-sbom-build.sh +++ b/scripts/initialize-sbom-build.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -euo pipefail diff --git a/test/validate-preflight-e2e.sh b/test/validate-preflight-e2e.sh index 90502d864..a6dc1ab5b 100755 --- a/test/validate-preflight-e2e.sh +++ b/test/validate-preflight-e2e.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -euo pipefail diff --git a/test/validate-support-bundle-e2e.sh b/test/validate-support-bundle-e2e.sh index 7c9300aff..98ca7ccfc 100755 --- a/test/validate-support-bundle-e2e.sh +++ b/test/validate-support-bundle-e2e.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -euo pipefail From 4a05b2391d750a9acd49ab3519788077611943ff Mon Sep 17 00:00:00 2001 From: Tom Wieczorek Date: Fri, 10 Feb 2023 18:26:16 +0100 Subject: [PATCH 25/55] 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. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index b99370d4b..5d01bec23 100644 --- a/Makefile +++ b/Makefile @@ -130,7 +130,7 @@ CONTROLLER_GEN=$(shell which controller-gen) .PHONY: client-gen client-gen: -ifeq (, $(shell which client-gen)) +ifeq (, $(shell which client-gen 2>/dev/null)) go install k8s.io/code-generator/cmd/client-gen@v0.26.1 CLIENT_GEN=$(shell go env GOPATH)/bin/client-gen else From ed70320f9648653fe909f830a783ac2390a48ac9 Mon Sep 17 00:00:00 2001 From: Tom Wieczorek Date: Fri, 10 Feb 2023 18:27:50 +0100 Subject: [PATCH 26/55] chore: remove unused code (#1013) Remove code snippets that are not used across the codebase. --- cmd/troubleshoot/cli/run.go | 33 --------------------- cmd/troubleshoot/cli/util.go | 24 ---------------- cmd/troubleshoot/cli/version.go | 28 ------------------ pkg/collect/collector.go | 7 ----- pkg/collect/configmap_test.go | 5 ---- pkg/collect/copy.go | 51 --------------------------------- pkg/collect/secret_test.go | 5 ---- pkg/debug/log.go | 3 -- pkg/oci/creds.go | 5 ---- pkg/specs/configmaps_test.go | 13 --------- pkg/specs/secrets_test.go | 13 --------- 11 files changed, 187 deletions(-) delete mode 100644 cmd/troubleshoot/cli/util.go delete mode 100644 pkg/oci/creds.go diff --git a/cmd/troubleshoot/cli/run.go b/cmd/troubleshoot/cli/run.go index 8385efba0..3298a3a1f 100644 --- a/cmd/troubleshoot/cli/run.go +++ b/cmd/troubleshoot/cli/run.go @@ -5,7 +5,6 @@ import ( "encoding/json" "fmt" "net/http" - "net/url" "os" "os/signal" "path/filepath" @@ -14,7 +13,6 @@ import ( cursor "github.com/ahmetalpbalkan/go-cursor" "github.com/fatih/color" - "github.com/manifoldco/promptui" "github.com/mattn/go-isatty" "github.com/pkg/errors" analyzer "github.com/replicatedhq/troubleshoot/pkg/analyze" @@ -340,14 +338,6 @@ the %s Admin Console to begin analysis.` return nil } -func getExpectedContentType(uploadURL string) string { - parsedURL, err := url.Parse(uploadURL) - if err != nil { - return "" - } - return parsedURL.Query().Get("Content-Type") -} - func parseTimeFlags(v *viper.Viper) (*time.Time, error) { var ( sinceTime time.Time @@ -373,29 +363,6 @@ func parseTimeFlags(v *viper.Viper) (*time.Time, error) { return &sinceTime, nil } -func shouldRetryRequest(err error) bool { - if strings.Contains(err.Error(), "x509") && canTryInsecure() { - httputil.AddTransport(&http.Transport{ - TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, - }) - return true - } - return false -} - -func canTryInsecure() bool { - if !isatty.IsTerminal(os.Stdout.Fd()) { - return false - } - prompt := promptui.Prompt{ - Label: "Connection appears to be insecure. Would you like to attempt to create a support bundle anyway?", - IsConfirm: true, - } - - _, err := prompt.Run() - return err == nil -} - type analysisOutput struct { Analysis []*analyzer.AnalyzeResult ArchivePath string diff --git a/cmd/troubleshoot/cli/util.go b/cmd/troubleshoot/cli/util.go deleted file mode 100644 index 738d301a0..000000000 --- a/cmd/troubleshoot/cli/util.go +++ /dev/null @@ -1,24 +0,0 @@ -package cli - -import ( - "fmt" - "os" - - "github.com/pkg/errors" -) - -func findFileName(basename, extension string) (string, error) { - n := 1 - name := basename - for { - filename := name + "." + extension - if _, err := os.Stat(filename); os.IsNotExist(err) { - return filename, nil - } else if err != nil { - return "", errors.Wrap(err, "check file exists") - } - - name = fmt.Sprintf("%s (%d)", basename, n) - n = n + 1 - } -} diff --git a/cmd/troubleshoot/cli/version.go b/cmd/troubleshoot/cli/version.go index 38bb26d17..061d39620 100644 --- a/cmd/troubleshoot/cli/version.go +++ b/cmd/troubleshoot/cli/version.go @@ -3,14 +3,8 @@ package cli import ( "fmt" - "io/ioutil" - "path/filepath" - - troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" - "github.com/replicatedhq/troubleshoot/pkg/constants" "github.com/replicatedhq/troubleshoot/pkg/version" "github.com/spf13/cobra" - "gopkg.in/yaml.v2" ) func VersionCmd() *cobra.Command { @@ -26,25 +20,3 @@ func VersionCmd() *cobra.Command { } return cmd } - -func writeVersionFile(path string) error { - version := troubleshootv1beta2.SupportBundleVersion{ - ApiVersion: "troubleshoot.sh/v1beta2", - Kind: "SupportBundle", - Spec: troubleshootv1beta2.SupportBundleVersionSpec{ - VersionNumber: version.Version(), - }, - } - b, err := yaml.Marshal(version) - if err != nil { - return err - } - - filename := filepath.Join(path, constants.VERSION_FILENAME) - err = ioutil.WriteFile(filename, b, 0644) - if err != nil { - return err - } - - return nil -} diff --git a/pkg/collect/collector.go b/pkg/collect/collector.go index 96bbf718c..72ffde1cb 100644 --- a/pkg/collect/collector.go +++ b/pkg/collect/collector.go @@ -106,13 +106,6 @@ func GetCollector(collector *troubleshootv1beta2.Collect, bundlePath string, nam } } -func collectorTitleOrDefault(meta troubleshootv1beta2.CollectorMeta, defaultTitle string) string { - if meta.CollectorName != "" { - return meta.CollectorName - } - return defaultTitle -} - func getCollectorName(c interface{}) string { var collector, name, selector string diff --git a/pkg/collect/configmap_test.go b/pkg/collect/configmap_test.go index 0df7e240c..58f021025 100644 --- a/pkg/collect/configmap_test.go +++ b/pkg/collect/configmap_test.go @@ -9,15 +9,10 @@ import ( "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes" testclient "k8s.io/client-go/kubernetes/fake" ) func TestConfigMap(t *testing.T) { - type args struct { - ctx context.Context - client kubernetes.Interface - } tests := []struct { name string configMapCollector *troubleshootv1beta2.ConfigMap diff --git a/pkg/collect/copy.go b/pkg/collect/copy.go index a19e63043..541e31818 100644 --- a/pkg/collect/copy.go +++ b/pkg/collect/copy.go @@ -6,7 +6,6 @@ import ( "context" "fmt" "io" - "io/ioutil" "os" "path/filepath" @@ -186,53 +185,3 @@ func getCopyErrosFileName(copyCollector *troubleshootv1beta2.Copy) string { // TODO: random part return "errors.json" } - -func extractTar(reader io.Reader) (map[string][]byte, error) { - files := map[string][]byte{} - - tr := tar.NewReader(reader) - for { - header, err := tr.Next() - if err == io.EOF { - break - } else if err != nil { - return files, errors.Wrap(err, "read header") - } - - switch header.Typeflag { - case tar.TypeReg: - data, err := ioutil.ReadAll(tr) - if err != nil { - return files, errors.Wrapf(err, "read file %s", header.Name) - } - files[header.Name] = data - default: - continue - } - } - - return files, nil -} - -func saveFromTar(rootDir string, reader io.Reader) (CollectorResult, error) { - result := NewResult() - - tr := tar.NewReader(reader) - for { - header, err := tr.Next() - if err == io.EOF { - break - } else if err != nil { - return result, errors.Wrap(err, "read header") - } - - switch header.Typeflag { - case tar.TypeReg: - result.SaveResult(rootDir, header.Name, tr) - default: - continue - } - } - - return result, nil -} diff --git a/pkg/collect/secret_test.go b/pkg/collect/secret_test.go index 6d4005802..ef4ee3ea0 100644 --- a/pkg/collect/secret_test.go +++ b/pkg/collect/secret_test.go @@ -10,15 +10,10 @@ import ( "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes" testclient "k8s.io/client-go/kubernetes/fake" ) func TestSecret(t *testing.T) { - type args struct { - ctx context.Context - client kubernetes.Interface - } tests := []struct { name string secretCollector *troubleshootv1beta2.Secret diff --git a/pkg/debug/log.go b/pkg/debug/log.go index 2e1087e79..ceb066f01 100644 --- a/pkg/debug/log.go +++ b/pkg/debug/log.go @@ -2,13 +2,10 @@ package debug import ( "log" - "os" "github.com/spf13/viper" ) -var logger = log.New(os.Stderr, "[debug]", log.Lshortfile) - func Print(v ...interface{}) { if viper.GetBool("debug") { log.Print(v...) diff --git a/pkg/oci/creds.go b/pkg/oci/creds.go deleted file mode 100644 index 4cd9af4f4..000000000 --- a/pkg/oci/creds.go +++ /dev/null @@ -1,5 +0,0 @@ -package oci - -func tryFindCreds(host string) (string, string, error) { - return "", "", nil -} diff --git a/pkg/specs/configmaps_test.go b/pkg/specs/configmaps_test.go index 628d4d3eb..5af86b7ba 100644 --- a/pkg/specs/configmaps_test.go +++ b/pkg/specs/configmaps_test.go @@ -8,15 +8,10 @@ import ( "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes" testclient "k8s.io/client-go/kubernetes/fake" ) func Test_LoadFromConfigMapMatchingLabel(t *testing.T) { - type args struct { - ctx context.Context - client kubernetes.Interface - } tests := []struct { name string supportBundleConfigMaps []corev1.ConfigMap @@ -376,10 +371,6 @@ spec: } func TestUserProvidedNamespace_LoadFromConfigMapMatchingLabel(t *testing.T) { - type args struct { - ctx context.Context - client kubernetes.Interface - } tests := []struct { name string supportBundleConfigMaps []corev1.ConfigMap @@ -472,10 +463,6 @@ spec: } func TestRedactors_LoadFromConfigMapMatchingLabel(t *testing.T) { - type args struct { - ctx context.Context - client kubernetes.Interface - } tests := []struct { name string supportBundleConfigMaps []corev1.ConfigMap diff --git a/pkg/specs/secrets_test.go b/pkg/specs/secrets_test.go index 682cc7a1a..491e14f80 100644 --- a/pkg/specs/secrets_test.go +++ b/pkg/specs/secrets_test.go @@ -8,15 +8,10 @@ import ( "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes" testclient "k8s.io/client-go/kubernetes/fake" ) func Test_LoadFromSecretMatchingLabel(t *testing.T) { - type args struct { - ctx context.Context - client kubernetes.Interface - } tests := []struct { name string supportBundleSecrets []corev1.Secret @@ -376,10 +371,6 @@ spec: } func TestUserProvidedNamespace_LoadFromSecretMatchingLabel(t *testing.T) { - type args struct { - ctx context.Context - client kubernetes.Interface - } tests := []struct { name string supportBundleSecrets []corev1.Secret @@ -472,10 +463,6 @@ spec: } func TestRedactors_LoadFromSecretMatchingLabel(t *testing.T) { - type args struct { - ctx context.Context - client kubernetes.Interface - } tests := []struct { name string supportBundleSecrets []corev1.Secret From 83c61baf82f1fbaa5d013c864084eee4dc61bbe1 Mon Sep 17 00:00:00 2001 From: Nick Meyer Date: Mon, 13 Feb 2023 12:04:04 -0600 Subject: [PATCH 27/55] remove PR label enforcement workflow (#1015) --- .github/workflows/require-pr-labels.yaml | 25 ------------------------ 1 file changed, 25 deletions(-) delete mode 100644 .github/workflows/require-pr-labels.yaml diff --git a/.github/workflows/require-pr-labels.yaml b/.github/workflows/require-pr-labels.yaml deleted file mode 100644 index b4eefdf5b..000000000 --- a/.github/workflows/require-pr-labels.yaml +++ /dev/null @@ -1,25 +0,0 @@ -name: Require pull request labels - -permissions: - pull-requests: read - -on: - pull_request: - types: - - opened - - labeled - - unlabeled - - synchronize - -jobs: - require-pr-labels: - uses: replicatedhq/reusable-workflows/.github/workflows/pr-enforce-labels.yaml@main - require-bug-labels: - runs-on: ubuntu-latest - steps: - - uses: mheap/github-action-required-labels@v3 - if: ${{ github.event.label.name == 'type::bug' }} - with: - mode: exactly - count: 1 - labels: "bug::normal, bug::regression" From 8b3c73cb4bc2c69f75207ac914c1f419faf33e03 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Feb 2023 17:36:39 +0000 Subject: [PATCH 28/55] 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> --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 83f68291a..a97edd176 100644 --- a/go.mod +++ b/go.mod @@ -34,8 +34,8 @@ require ( github.com/spf13/viper v1.15.0 github.com/stretchr/testify v1.8.1 github.com/tj/go-spin v1.1.0 - go.opentelemetry.io/otel v1.12.0 - go.opentelemetry.io/otel/sdk v1.11.2 + go.opentelemetry.io/otel v1.13.0 + go.opentelemetry.io/otel/sdk v1.13.0 golang.org/x/sync v0.1.0 gopkg.in/yaml.v2 v2.4.0 k8s.io/api v0.26.1 @@ -67,7 +67,7 @@ require ( github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sylabs/sif/v2 v2.9.0 // indirect - go.opentelemetry.io/otel/trace v1.12.0 // indirect + go.opentelemetry.io/otel/trace v1.13.0 // indirect golang.org/x/mod v0.7.0 // indirect golang.org/x/tools v0.4.0 // indirect ) diff --git a/go.sum b/go.sum index d9c37259f..54de90419 100644 --- a/go.sum +++ b/go.sum @@ -1066,12 +1066,12 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/otel v1.12.0 h1:IgfC7kqQrRccIKuB7Cl+SRUmsKbEwSGPr0Eu+/ht1SQ= -go.opentelemetry.io/otel v1.12.0/go.mod h1:geaoz0L0r1BEOR81k7/n9W4TCXYCJ7bPO7K374jQHG0= -go.opentelemetry.io/otel/sdk v1.11.2 h1:GF4JoaEx7iihdMFu30sOyRx52HDHOkl9xQ8SMqNXUiU= -go.opentelemetry.io/otel/sdk v1.11.2/go.mod h1:wZ1WxImwpq+lVRo4vsmSOxdd+xwoUJ6rqyLc3SyX9aU= -go.opentelemetry.io/otel/trace v1.12.0 h1:p28in++7Kd0r2d8gSt931O57fdjUyWxkVbESuILAeUc= -go.opentelemetry.io/otel/trace v1.12.0/go.mod h1:pHlgBynn6s25qJ2szD+Bv+iwKJttjHSI3lUAyf0GNuQ= +go.opentelemetry.io/otel v1.13.0 h1:1ZAKnNQKwBBxFtww/GwxNUyTf0AxkZzrukO8MeXqe4Y= +go.opentelemetry.io/otel v1.13.0/go.mod h1:FH3RtdZCzRkJYFTCsAKDy9l/XYjMdNv6QrkFFB8DvVg= +go.opentelemetry.io/otel/sdk v1.13.0 h1:BHib5g8MvdqS65yo2vV1s6Le42Hm6rrw08qU6yz5JaM= +go.opentelemetry.io/otel/sdk v1.13.0/go.mod h1:YLKPx5+6Vx/o1TCUYYs+bpymtkmazOMT6zoRrC7AQ7I= +go.opentelemetry.io/otel/trace v1.13.0 h1:CBgRZ6ntv+Amuj1jDsMhZtlAPT6gbyIRdaIzFhfBSdY= +go.opentelemetry.io/otel/trace v1.13.0/go.mod h1:muCvmmO9KKpvuXSf3KKAXXB2ygNYHQ+ZfI5X08d3tds= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 h1:+FNtrFTmVw0YZGpBGX56XDee331t6JAXeK2bcyhLOOc= go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o= From ac53a2167cbbddb724009dcb27cfb0498b07e753 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Feb 2023 17:39:31 +0000 Subject: [PATCH 29/55] 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> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index a97edd176..66f6b8234 100644 --- a/go.mod +++ b/go.mod @@ -193,7 +193,7 @@ require ( golang.org/x/oauth2 v0.4.0 // indirect golang.org/x/sys v0.4.0 // indirect golang.org/x/term v0.4.0 // indirect - golang.org/x/text v0.6.0 + golang.org/x/text v0.7.0 golang.org/x/time v0.3.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/api v0.107.0 // indirect diff --git a/go.sum b/go.sum index 54de90419..dc8d706ab 100644 --- a/go.sum +++ b/go.sum @@ -1338,8 +1338,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k= -golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= From b135f20945da5e576a95bbc4f40a907b42cb4c41 Mon Sep 17 00:00:00 2001 From: Chase Hainey Date: Mon, 20 Mar 2023 12:40:34 -0600 Subject: [PATCH 30/55] 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> --- go.mod | 12 ++++++------ go.sum | 13 +++++++------ 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 66f6b8234..2f416c6b8 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/gorilla/handlers v1.5.1 github.com/hashicorp/go-getter v1.6.2 github.com/hashicorp/go-multierror v1.1.1 - github.com/jackc/pgx/v5 v5.2.0 + github.com/jackc/pgx/v5 v5.3.0 github.com/longhorn/go-iscsi-helper v0.0.0-20210330030558-49a327fb024e github.com/manifoldco/promptui v0.9.0 github.com/mattn/go-isatty v0.0.17 @@ -60,7 +60,7 @@ require ( github.com/go-logr/stdr v1.2.2 // 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-20200714003250-2b9c44734f2b // indirect + github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/microsoft/go-mssqldb v0.18.0 // indirect github.com/mistifyio/go-zfs/v3 v3.0.0 // indirect @@ -188,11 +188,11 @@ require ( github.com/yusufpapurcu/wmi v1.2.2 // indirect go.opencensus.io v0.24.0 // indirect go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect - golang.org/x/crypto v0.5.0 // indirect - golang.org/x/net v0.5.0 // indirect + golang.org/x/crypto v0.6.0 // indirect + golang.org/x/net v0.6.0 // indirect golang.org/x/oauth2 v0.4.0 // indirect - golang.org/x/sys v0.4.0 // indirect - golang.org/x/term v0.4.0 // indirect + golang.org/x/sys v0.5.0 // indirect + golang.org/x/term v0.5.0 // indirect golang.org/x/text v0.7.0 golang.org/x/time v0.3.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect diff --git a/go.sum b/go.sum index dc8d706ab..4e9bd8f37 100644 --- a/go.sum +++ b/go.sum @@ -1077,7 +1077,7 @@ go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 h1:+FNtrFTmVw0YZGpBGX56XDee33 go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= +go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= @@ -1194,8 +1194,8 @@ golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qx 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.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw= -golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.6.0 h1:L4ZwwTvKW9gr0ZMS1yrHD9GZhIuVjOBBnaKH+SPQK0Q= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1324,12 +1324,13 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.4.0 h1:O7UWfv5+A2qiuulQk30kVinPoMtoIPeVaKLEgLpVkvg= -golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= +golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= From 7e3054edaa354581a36159cf232d77ad3f881217 Mon Sep 17 00:00:00 2001 From: Chase Hainey Date: Mon, 20 Mar 2023 12:41:42 -0600 Subject: [PATCH 31/55] 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> --- go.mod | 8 +- go.sum | 378 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 372 insertions(+), 14 deletions(-) diff --git a/go.mod b/go.mod index 2f416c6b8..3772e304b 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/google/gofuzz v1.2.0 github.com/google/uuid v1.3.0 github.com/gorilla/handlers v1.5.1 - github.com/hashicorp/go-getter v1.6.2 + github.com/hashicorp/go-getter v1.7.0 github.com/hashicorp/go-multierror v1.1.1 github.com/jackc/pgx/v5 v5.3.0 github.com/longhorn/go-iscsi-helper v0.0.0-20210330030558-49a327fb024e @@ -82,7 +82,7 @@ require ( github.com/Microsoft/go-winio v0.6.0 // indirect github.com/Microsoft/hcsshim v0.9.6 // indirect github.com/andybalholm/brotli v1.0.1 // indirect - github.com/aws/aws-sdk-go v1.43.16 // indirect + github.com/aws/aws-sdk-go v1.44.122 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect github.com/c9s/goprocinfo v0.0.0-20170724085704-0010a05ce49f // indirect @@ -128,7 +128,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.3.0 // indirect + github.com/hashicorp/go-version v1.6.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/imdario/mergo v0.3.13 // indirect github.com/inconshreveable/mousetrap v1.0.1 // indirect @@ -145,7 +145,7 @@ require ( github.com/mattn/go-shellwords v1.0.12 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect - github.com/mitchellh/go-testing-interface v1.0.0 // indirect + github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mitchellh/go-wordwrap v1.0.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/moby/locker v1.0.1 // indirect diff --git a/go.sum b/go.sum index 4e9bd8f37..0086b6471 100644 --- a/go.sum +++ b/go.sum @@ -18,35 +18,176 @@ cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHOb cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= +cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= +cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= +cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= +cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= +cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= +cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= +cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= +cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= +cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= +cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= +cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= +cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= +cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU= +cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= cloud.google.com/go v0.105.0 h1:DNtEKRBAAzeS4KyIory52wWHuClNaXJ5x1F7xa4q+5Y= cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFOKM= +cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw= +cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= +cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI= +cloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4= +cloud.google.com/go/area120 v0.5.0/go.mod h1:DE/n4mp+iqVyvxHN41Vf1CR602GiHQjFPusMFW6bGR4= +cloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0= +cloud.google.com/go/artifactregistry v1.6.0/go.mod h1:IYt0oBPSAGYj/kprzsBjZ/4LnG/zOcHyFHjWPCi6SAQ= +cloud.google.com/go/artifactregistry v1.7.0/go.mod h1:mqTOFOnGZx8EtSqK/ZWcsm/4U8B77rbcLP6ruDU2Ixk= +cloud.google.com/go/asset v1.5.0/go.mod h1:5mfs8UvcM5wHhqtSv8J1CtxxaQq3AdBxxQi2jGW/K4o= +cloud.google.com/go/asset v1.7.0/go.mod h1:YbENsRK4+xTiL+Ofoj5Ckf+O17kJtgp3Y3nn4uzZz5s= +cloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjbytpUaW0= +cloud.google.com/go/assuredworkloads v1.5.0/go.mod h1:n8HOZ6pff6re5KYfBXcFvSViQjDwxFkAkmUFffJRbbY= +cloud.google.com/go/assuredworkloads v1.6.0/go.mod h1:yo2YOk37Yc89Rsd5QMVECvjaMKymF9OP+QXWlKXUkXw= +cloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVoYoxeLBoj4XkKYscNI= +cloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0= +cloud.google.com/go/automl v1.6.0/go.mod h1:ugf8a6Fx+zP0D59WLhqgTDsQI9w07o64uf/Is3Nh5p8= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/bigquery v1.42.0/go.mod h1:8dRTJxhtG+vwBKzE5OseQn/hiydoQN3EedCaOdYmxRA= +cloud.google.com/go/billing v1.4.0/go.mod h1:g9IdKBEFlItS8bTtlrZdVLWSSdSyFUZKXNS02zKMOZY= +cloud.google.com/go/billing v1.5.0/go.mod h1:mztb1tBc3QekhjSgmpf/CV4LzWXLzCArwpLmP2Gm88s= +cloud.google.com/go/binaryauthorization v1.1.0/go.mod h1:xwnoWu3Y84jbuHa0zd526MJYmtnVXn0syOjaJgy4+dM= +cloud.google.com/go/binaryauthorization v1.2.0/go.mod h1:86WKkJHtRcv5ViNABtYMhhNWRrD1Vpi//uKEy7aYEfI= +cloud.google.com/go/cloudtasks v1.5.0/go.mod h1:fD92REy1x5woxkKEkLdvavGnPJGEn8Uic9nWuLzqCpY= +cloud.google.com/go/cloudtasks v1.6.0/go.mod h1:C6Io+sxuke9/KNRkbQpihnW93SWDU3uXt92nu85HkYI= +cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= +cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= +cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= +cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= +cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= +cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= +cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU= cloud.google.com/go/compute v1.14.0 h1:hfm2+FfxVmnRlh6LpB7cg1ZNU+5edAHmW679JePztk0= cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvjxega5vAdo= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= +cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I= +cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4= +cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0= +cloud.google.com/go/datacatalog v1.5.0/go.mod h1:M7GPLNQeLfWqeIm3iuiruhPzkt65+Bx8dAKvScX8jvs= +cloud.google.com/go/datacatalog v1.6.0/go.mod h1:+aEyF8JKg+uXcIdAmmaMUmZ3q1b/lKLtXCmXdnc0lbc= +cloud.google.com/go/dataflow v0.6.0/go.mod h1:9QwV89cGoxjjSR9/r7eFDqqjtvbKxAK2BaYU6PVk9UM= +cloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ= +cloud.google.com/go/dataform v0.3.0/go.mod h1:cj8uNliRlHpa6L3yVhDOBrUXH+BPAO1+KFMQQNSThKo= +cloud.google.com/go/dataform v0.4.0/go.mod h1:fwV6Y4Ty2yIFL89huYlEkwUPtS7YZinZbzzj5S9FzCE= +cloud.google.com/go/datalabeling v0.5.0/go.mod h1:TGcJ0G2NzcsXSE/97yWjIZO0bXj0KbVlINXMG9ud42I= +cloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ= +cloud.google.com/go/dataqna v0.5.0/go.mod h1:90Hyk596ft3zUQ8NkFfvICSIfHFh1Bc7C4cK3vbhkeo= +cloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/datastream v1.2.0/go.mod h1:i/uTP8/fZwgATHS/XFu0TcNUhuA0twZxxQ3EyCUQMwo= +cloud.google.com/go/datastream v1.3.0/go.mod h1:cqlOX8xlyYF/uxhiKn6Hbv6WjwPPuI9W2M9SAXwaLLQ= +cloud.google.com/go/dialogflow v1.15.0/go.mod h1:HbHDWs33WOGJgn6rfzBW1Kv807BE3O1+xGbn59zZWI4= +cloud.google.com/go/dialogflow v1.16.1/go.mod h1:po6LlzGfK+smoSmTBnbkIZY2w8ffjz/RcGSS+sh1el0= +cloud.google.com/go/dialogflow v1.17.0/go.mod h1:YNP09C/kXA1aZdBgC/VtXX74G/TKn7XVCcVumTflA+8= +cloud.google.com/go/documentai v1.7.0/go.mod h1:lJvftZB5NRiFSX4moiye1SMxHx0Bc3x1+p9e/RfXYiU= +cloud.google.com/go/documentai v1.8.0/go.mod h1:xGHNEB7CtsnySCNrCFdCyyMz44RhFEEX2Q7UD0c5IhU= +cloud.google.com/go/domains v0.6.0/go.mod h1:T9Rz3GasrpYk6mEGHh4rymIhjlnIuB4ofT1wTxDeT4Y= +cloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg= +cloud.google.com/go/edgecontainer v0.1.0/go.mod h1:WgkZ9tp10bFxqO8BLPqv2LlfmQF1X8lZqwW4r1BTajk= +cloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w= +cloud.google.com/go/functions v1.6.0/go.mod h1:3H1UA3qiIPRWD7PeZKLvHZ9SaQhR26XIJcC0A5GbvAk= +cloud.google.com/go/functions v1.7.0/go.mod h1:+d+QBcWM+RsrgZfV9xo6KfA1GlzJfxcfZcRPEhDDfzg= +cloud.google.com/go/gaming v1.5.0/go.mod h1:ol7rGcxP/qHTRQE/RO4bxkXq+Fix0j6D4LFPzYTIrDM= +cloud.google.com/go/gaming v1.6.0/go.mod h1:YMU1GEvA39Qt3zWGyAVA9bpYz/yAhTvaQ1t2sK4KPUA= +cloud.google.com/go/gkeconnect v0.5.0/go.mod h1:c5lsNAg5EwAy7fkqX/+goqFsU1Da/jQFqArp+wGNr/o= +cloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A= +cloud.google.com/go/gkehub v0.9.0/go.mod h1:WYHN6WG8w9bXU0hqNxt8rm5uxnk8IH+lPY9J2TV7BK0= +cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0= +cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc= +cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= +cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= cloud.google.com/go/iam v0.8.0 h1:E2osAkZzxI/+8pZcxVLcDtAQx/u+hZXVryUaYQ5O0Kk= cloud.google.com/go/iam v0.8.0/go.mod h1:lga0/y3iH6CX7sYqypWJ33hf7kkfXJag67naqGESjkE= +cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic= +cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= +cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8= +cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= cloud.google.com/go/longrunning v0.3.0 h1:NjljC+FYPV3uh5/OwWT6pVU+doBqMg2x/rZlE+CamDs= +cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4= +cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= +cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE= +cloud.google.com/go/memcache v1.5.0/go.mod h1:dk3fCK7dVo0cUU2c36jKb4VqKPS22BTkf81Xq617aWM= +cloud.google.com/go/metastore v1.5.0/go.mod h1:2ZNrDcQwghfdtCwJ33nM0+GrBGlVuh8rakL3vdPY3XY= +cloud.google.com/go/metastore v1.6.0/go.mod h1:6cyQTls8CWXzk45G55x57DVQ9gWg7RiH65+YgPsNh9s= +cloud.google.com/go/networkconnectivity v1.4.0/go.mod h1:nOl7YL8odKyAOtzNX73/M5/mGZgqqMeryi6UPZTk/rA= +cloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o= +cloud.google.com/go/networksecurity v0.5.0/go.mod h1:xS6fOCoqpVC5zx15Z/MqkfDwH4+m/61A3ODiDV1xmiQ= +cloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU= +cloud.google.com/go/notebooks v1.2.0/go.mod h1:9+wtppMfVPUeJ8fIWPOq1UnATHISkGXGqTkxeieQ6UY= +cloud.google.com/go/notebooks v1.3.0/go.mod h1:bFR5lj07DtCPC7YAAJ//vHskFBxA5JzYlH68kXVdk34= +cloud.google.com/go/osconfig v1.7.0/go.mod h1:oVHeCeZELfJP7XLxcBGTMBvRO+1nQ5tFG9VQTmYS2Fs= +cloud.google.com/go/osconfig v1.8.0/go.mod h1:EQqZLu5w5XA7eKizepumcvWx+m8mJUhEwiPqWiZeEdg= +cloud.google.com/go/oslogin v1.4.0/go.mod h1:YdgMXWRaElXz/lDk1Na6Fh5orF7gvmJ0FGLIs9LId4E= +cloud.google.com/go/oslogin v1.5.0/go.mod h1:D260Qj11W2qx/HVF29zBg+0fd6YCSjSqLUkY/qEenQU= +cloud.google.com/go/phishingprotection v0.5.0/go.mod h1:Y3HZknsK9bc9dMi+oE8Bim0lczMU6hrX0UpADuMefr0= +cloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA= +cloud.google.com/go/privatecatalog v0.5.0/go.mod h1:XgosMUvvPyxDjAVNDYxJ7wBW8//hLDDYmnsNcMGq1K0= +cloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/recaptchaenterprise v1.3.1/go.mod h1:OdD+q+y4XGeAlxRaMn1Y7/GveP6zmq76byL6tjPE7d4= +cloud.google.com/go/recaptchaenterprise/v2 v2.1.0/go.mod h1:w9yVqajwroDNTfGuhmOjPDN//rZGySaf6PtFVcSCa7o= +cloud.google.com/go/recaptchaenterprise/v2 v2.2.0/go.mod h1:/Zu5jisWGeERrd5HnlS3EUGb/D335f9k51B/FVil0jk= +cloud.google.com/go/recaptchaenterprise/v2 v2.3.0/go.mod h1:O9LwGCjrhGHBQET5CA7dd5NwwNQUErSgEDit1DLNTdo= +cloud.google.com/go/recommendationengine v0.5.0/go.mod h1:E5756pJcVFeVgaQv3WNpImkFP8a+RptV6dDLGPILjvg= +cloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4= +cloud.google.com/go/recommender v1.5.0/go.mod h1:jdoeiBIVrJe9gQjwd759ecLJbxCDED4A6p+mqoqDvTg= +cloud.google.com/go/recommender v1.6.0/go.mod h1:+yETpm25mcoiECKh9DEScGzIRyDKpZ0cEhWGo+8bo+c= +cloud.google.com/go/redis v1.7.0/go.mod h1:V3x5Jq1jzUcg+UNsRvdmsfuFnit1cfe3Z/PGyq/lm4Y= +cloud.google.com/go/redis v1.8.0/go.mod h1:Fm2szCDavWzBk2cDKxrkmWBqoCiL1+Ctwq7EyqBCA/A= +cloud.google.com/go/retail v1.8.0/go.mod h1:QblKS8waDmNUhghY2TI9O3JLlFk8jybHeV4BF19FrE4= +cloud.google.com/go/retail v1.9.0/go.mod h1:g6jb6mKuCS1QKnH/dpu7isX253absFl6iE92nHwlBUY= +cloud.google.com/go/scheduler v1.4.0/go.mod h1:drcJBmxF3aqZJRhmkHQ9b3uSSpQoltBPGPxGAWROx6s= +cloud.google.com/go/scheduler v1.5.0/go.mod h1:ri073ym49NW3AfT6DZi21vLZrG07GXr5p3H1KxN5QlI= +cloud.google.com/go/secretmanager v1.6.0/go.mod h1:awVa/OXF6IiyaU1wQ34inzQNc4ISIDIrId8qE5QGgKA= +cloud.google.com/go/security v1.5.0/go.mod h1:lgxGdyOKKjHL4YG3/YwIL2zLqMFCKs0UbQwgyZmfJl4= +cloud.google.com/go/security v1.7.0/go.mod h1:mZklORHl6Bg7CNnnjLH//0UlAlaXqiG7Lb9PsPXLfD0= +cloud.google.com/go/security v1.8.0/go.mod h1:hAQOwgmaHhztFhiQ41CjDODdWP0+AE1B3sX4OFlq+GU= +cloud.google.com/go/securitycenter v1.13.0/go.mod h1:cv5qNAqjY84FCN6Y9z28WlkKXyWsgLO832YiWwkCWcU= +cloud.google.com/go/securitycenter v1.14.0/go.mod h1:gZLAhtyKv85n52XYWt6RmeBdydyxfPeTrpToDPw4Auc= +cloud.google.com/go/servicedirectory v1.4.0/go.mod h1:gH1MUaZCgtP7qQiI+F+A+OpeKF/HQWgtAddhTbhL2bs= +cloud.google.com/go/servicedirectory v1.5.0/go.mod h1:QMKFL0NUySbpZJ1UZs3oFAmdvVxhhxB6eJ/Vlp73dfg= +cloud.google.com/go/speech v1.6.0/go.mod h1:79tcr4FHCimOp56lwC01xnt/WPJZc4v3gzyT7FoBkCM= +cloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= +cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= +cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= cloud.google.com/go/storage v1.27.0 h1:YOO045NZI9RKfCj1c5A/ZtuuENUc8OAW+gHdGnDgyMQ= cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= +cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw= +cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g= +cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU= +cloud.google.com/go/videointelligence v1.7.0/go.mod h1:k8pI/1wAhjznARtVT9U1llUaFNPh7muw8QyOUpavru4= +cloud.google.com/go/vision v1.2.0/go.mod h1:SmNwgObm5DpFBme2xpyOyasvBc1aPdjvMk2bBk0tKD0= +cloud.google.com/go/vision/v2 v2.2.0/go.mod h1:uCdV4PpN1S0jyCyq8sIM42v2Y6zOLkZs+4R9LrGYwFo= +cloud.google.com/go/vision/v2 v2.3.0/go.mod h1:UO61abBx9QRMFkNBbf1D8B1LXdS2cGiiCRx0vSpZoUo= +cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xXZmFiHmGE= +cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= +cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= +cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= 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= @@ -117,9 +258,8 @@ github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5 github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= -github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM= -github.com/aws/aws-sdk-go v1.43.16 h1:Y7wBby44f+tINqJjw5fLH3vA+gFq4uMITIKqditwM14= -github.com/aws/aws-sdk-go v1.43.16/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.44.122 h1:p6mw01WBaNpbdP2xrisz5tIkcNwzj/HysobNoaAHjgo= +github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= @@ -175,7 +315,12 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE= github.com/containerd/aufs v0.0.0-20201003224125-76a6863f2989/go.mod h1:AkGGQs9NM2vtYHaUen+NljV0/baGCAPELGm2q9ZXpWU= @@ -364,7 +509,10 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= @@ -479,6 +627,7 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -495,9 +644,11 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/gomodule/redigo v1.8.2 h1:H5XSIre1MB5NbPYFp+i1NBbb5qN1W8Y8YAQoAYbkm8k= @@ -519,6 +670,8 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-containerregistry v0.5.1/go.mod h1:Ct15B4yir3PLOP5jsy0GNeYVaIZs/MK/Jz5any1wFW0= @@ -533,6 +686,7 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.2.1 h1:d8MncMlErDFTwQGBK1xhv026j9kqhvw1Qv9IbWT1VLQ= +github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= @@ -543,6 +697,11 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= @@ -552,13 +711,24 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= github.com/googleapis/enterprise-certificate-proxy v0.2.1 h1:RY7tHKZcRlk788d5WSo/e83gOyyy742E8GSs771ySpg= github.com/googleapis/enterprise-certificate-proxy v0.2.1/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= +github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= +github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= +github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= +github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= +github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo= +github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= github.com/googleapis/gax-go/v2 v2.7.0 h1:IcsPKeInNvYi7eqSaDjiZqDDKu5rsmunY0Y1YupQSSQ= github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= +github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= @@ -587,18 +757,23 @@ github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-getter v1.6.2 h1:7jX7xcB+uVCliddZgeKyNxv0xoT7qL5KDtH7rU4IqIk= -github.com/hashicorp/go-getter v1.6.2/go.mod h1:IZCrswsZPeWv9IkVnLElzRU/gz/QPi6pZHn4tv6vbwA= +github.com/hashicorp/go-getter v1.7.0 h1:bzrYP+qu/gMrL1au7/aDvkoOVGUJpeKBgbqRHACAFDY= +github.com/hashicorp/go-getter v1.7.0/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744= github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= 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= +<<<<<<< HEAD github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.3.0 h1:McDWVJIU/y+u1BRV06dPaLfLCaT7fUTJLp5r04x7iNw= github.com/hashicorp/go-version v1.3.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +======= +github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= +github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +>>>>>>> 661a948 (chore(deps): bump github.com/hashicorp/go-getter from 1.6.2 to 1.7.0 (#1019)) github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= @@ -658,10 +833,10 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.11.2/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw= github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4= @@ -733,11 +908,10 @@ github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WT github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= github.com/mistifyio/go-zfs/v3 v3.0.0 h1:J5QK618xRcXnQYZ2GE5FdmpS1ufIrWue+lR/mpe6/14= github.com/mistifyio/go-zfs/v3 v3.0.0/go.mod h1:CzVgeB0RvF2EGzQnytKVvVSDwmKJXxkOTUGbNrTja/k= -github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0= -github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= +github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= @@ -1013,6 +1187,7 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1 github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ulikunitz/xz v0.5.9/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= @@ -1044,6 +1219,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 h1:+lm10QQTNSBd8DVTNGHx7o/IKu9HYDvLMffDhbyLccI= @@ -1064,6 +1240,7 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/otel v1.13.0 h1:1ZAKnNQKwBBxFtww/GwxNUyTf0AxkZzrukO8MeXqe4Y= @@ -1097,6 +1274,7 @@ golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPh 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.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= @@ -1130,6 +1308,7 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -1141,6 +1320,7 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1187,13 +1367,26 @@ golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +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= +golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.6.0 h1:L4ZwwTvKW9gr0ZMS1yrHD9GZhIuVjOBBnaKH+SPQK0Q= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1205,8 +1398,22 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= golang.org/x/oauth2 v0.4.0 h1:NF0gk8LVPg1Ml7SSbGyySuoxdsXitj7TvgvuRxIMc/M= golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1220,6 +1427,9 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1297,38 +1507,63 @@ golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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= +<<<<<<< HEAD golang.org/x/sys v0.0.0-20220224120231-95c6836cb0e7/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +======= +>>>>>>> 661a948 (chore(deps): bump github.com/hashicorp/go-getter from 1.6.2 to 1.7.0 (#1019)) 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-20220517195934-5e4e11fc645e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1337,8 +1572,10 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1409,12 +1646,20 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.4.0 h1:7mTAgkunk3fr4GAloyyCasadO6h9zSsQZbwvcaIciV4= golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY= @@ -1438,6 +1683,35 @@ google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz513 google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= +google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= +google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= +google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= +google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= +google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= +google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= +google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= +google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= +google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= +google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= +google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= +google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= +google.golang.org/api v0.77.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= +google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= +google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg= +google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= +google.golang.org/api v0.85.0/go.mod h1:AqZf8Ep9uZ2pyTvgL+x0D3Zt0eoT9b5E8fmzfu6FO2g= +google.golang.org/api v0.90.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= +google.golang.org/api v0.93.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= +google.golang.org/api v0.95.0/go.mod h1:eADj+UBuxkh5zlrSntJghuNeg8HwQ1w5lTKkuqaETEI= +google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70= google.golang.org/api v0.107.0 h1:I2SlFjD8ZWabaIFOfeEDg3pf0BHJDh6iYQ1ic3Yu/UU= google.golang.org/api v0.107.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= @@ -1490,7 +1764,73 @@ google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= +google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= +google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220722212130-b98a9ff5e252/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE= +google.golang.org/genproto v0.0.0-20220801145646-83ce21fca29f/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc= +google.golang.org/genproto v0.0.0-20220815135757-37a418bb8959/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220817144833-d7fd3f11b9b1/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220829144015-23454907ede3/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220829175752-36a9c930ecbf/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220913154956-18f8339a66a5/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220914142337-ca0e39ece12f/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220915135415-7fd63a7952de/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220916172020-2692e8806bfa/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220919141832-68c03719ef51/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220920201722-2b89144ce006/go.mod h1:ht8XFiar2npT/g4vkk7O0WYS1sHOHbdujxbEp7CJWbw= +google.golang.org/genproto v0.0.0-20220926165614-551eb538f295/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= +google.golang.org/genproto v0.0.0-20220926220553-6981cbe3cfce/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= +google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqwhZAwq4wsRUaVG555sVgsNmIjRtO7t/JH29U= +google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= +google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= +google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef h1:uQ2vjV/sHTsWSqdKeLqmwitzgvjMl7o4IdtHwUDXSJY= google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= @@ -1515,9 +1855,26 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.52.0 h1:kd48UiU7EHsV4rnLyOJRuP/Il/UHE7gdDAQ+SZI7nZk= google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1531,6 +1888,7 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= From aea2fd61bb683794be0b3906b16a17b79c2c4b1e Mon Sep 17 00:00:00 2001 From: Tom Wieczorek Date: Wed, 15 Feb 2023 20:13:35 +0100 Subject: [PATCH 32/55] 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 --- cmd/troubleshoot/cli/run.go | 55 ++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 29 deletions(-) diff --git a/cmd/troubleshoot/cli/run.go b/cmd/troubleshoot/cli/run.go index 3298a3a1f..c23cfeb3b 100644 --- a/cmd/troubleshoot/cli/run.go +++ b/cmd/troubleshoot/cli/run.go @@ -9,6 +9,7 @@ import ( "os/signal" "path/filepath" "strings" + "sync" "time" cursor "github.com/ahmetalpbalkan/go-cursor" @@ -208,34 +209,42 @@ func runTroubleshoot(v *viper.Viper, arg []string) error { } additionalRedactors.Spec.Redactors = append(additionalRedactors.Spec.Redactors, redactors...) - var collectorCB func(chan interface{}, string) - progressChan := make(chan interface{}) // non-zero buffer can result in missed messages - finishedCh := make(chan bool, 1) - isFinishedChClosed := false + var wg sync.WaitGroup + collectorCB := func(c chan interface{}, msg string) { c <- msg } + progressChan := make(chan interface{}) + isProgressChanClosed := false + defer func() { + if !isProgressChanClosed { + close(progressChan) + } + wg.Wait() + }() if !interactive { // TODO (dans): custom warning handler to capture warning in `analysisOutput` restConfig.WarningHandler = rest.NoWarnings{} - collectorCB = func(ch chan interface{}, name string) { - return - } // TODO (dans): maybe log to file + wg.Add(1) go func() { - for { - select { - case _ = <-progressChan: - // do nothing - } + defer wg.Done() + for msg := range progressChan { + logger.Printf("Collecting support bundle: %v", msg) } }() } else { s := spin.New() + wg.Add(1) go func() { + defer wg.Done() currentDir := "" for { select { - case msg := <-progressChan: + case msg, ok := <-progressChan: + if !ok { + fmt.Printf("\r%s\r", cursor.ClearEntireLine()) + return + } switch msg := msg.(type) { case error: c := color.New(color.FgHiRed) @@ -243,9 +252,6 @@ func runTroubleshoot(v *viper.Viper, arg []string) error { case string: currentDir = filepath.Base(msg) } - case <-finishedCh: - fmt.Printf("\r%s\r", cursor.ClearEntireLine()) - return case <-time.After(time.Millisecond * 100): if currentDir == "" { fmt.Printf("\r%s \033[36mCollecting support bundle\033[m %s", cursor.ClearEntireLine(), s.Next()) @@ -255,16 +261,6 @@ func runTroubleshoot(v *viper.Viper, arg []string) error { } } }() - defer func() { - if !isFinishedChClosed { - close(finishedCh) - } - }() - - collectorCB = func(c chan interface{}, msg string) { - c <- fmt.Sprintf("%s", msg) - } - } createOpts := supportbundle.SupportBundleCreateOpts{ @@ -290,11 +286,12 @@ func runTroubleshoot(v *viper.Viper, arg []string) error { if err != nil { return errors.Wrap(err, "failed to run collect and analyze process") } + + close(progressChan) // this removes the spinner in interactive mode + isProgressChanClosed = true + if len(response.AnalyzerResults) > 0 { if interactive { - close(finishedCh) // this removes the spinner - isFinishedChClosed = true - if err := showInteractiveResults(mainBundle.Name, response.AnalyzerResults); err != nil { interactive = false } From 41e9601975c0e014836a77428dd888f7f9275908 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Feb 2023 10:21:59 +0000 Subject: [PATCH 33/55] 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> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 3772e304b..2d6f5ca6f 100644 --- a/go.mod +++ b/go.mod @@ -89,7 +89,7 @@ require ( github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/chzyer/readline v1.5.1 // indirect github.com/containerd/cgroups v1.0.4 // indirect - github.com/containerd/containerd v1.6.12 // indirect + github.com/containerd/containerd v1.6.18 // indirect github.com/containerd/stargz-snapshotter/estargz v0.13.0 // indirect github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 // indirect github.com/containers/ocicrypt v1.1.7 // indirect diff --git a/go.sum b/go.sum index 0086b6471..8a4dac1d0 100644 --- a/go.sum +++ b/go.sum @@ -358,8 +358,8 @@ github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09Zvgq github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s= github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g= github.com/containerd/containerd v1.5.7/go.mod h1:gyvv6+ugqY25TiXxcZC3L5yOeYgEw0QMhscqVp1AR9c= -github.com/containerd/containerd v1.6.12 h1:kJ9b3mOFKf8yqo05Ob+tMoxvt1pbVWhnB0re9Y+k+8c= -github.com/containerd/containerd v1.6.12/go.mod h1:K4Bw7gjgh4TnkmQY+py/PYQGp4e7xgnHAeg87VeWb3A= +github.com/containerd/containerd v1.6.18 h1:qZbsLvmyu+Vlty0/Ex5xc0z2YtKpIsb5n45mAMI+2Ns= +github.com/containerd/containerd v1.6.18/go.mod h1:1RdCUu95+gc2v9t3IL+zIlpClSmew7/0YS8O5eQZrOw= github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= From 86dd407a70c837a54bf0534322077e14a88a1ff4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Feb 2023 14:33:33 +0000 Subject: [PATCH 34/55] 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> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 2d6f5ca6f..20477662e 100644 --- a/go.mod +++ b/go.mod @@ -189,7 +189,7 @@ require ( go.opencensus.io v0.24.0 // indirect go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect golang.org/x/crypto v0.6.0 // indirect - golang.org/x/net v0.6.0 // indirect + golang.org/x/net v0.7.0 // indirect golang.org/x/oauth2 v0.4.0 // indirect golang.org/x/sys v0.5.0 // indirect golang.org/x/term v0.5.0 // indirect diff --git a/go.sum b/go.sum index 8a4dac1d0..2df86e533 100644 --- a/go.sum +++ b/go.sum @@ -1387,8 +1387,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.6.0 h1:L4ZwwTvKW9gr0ZMS1yrHD9GZhIuVjOBBnaKH+SPQK0Q= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= From 33f30608ce8d56d3004f24be23c0d28c43ae1ff7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Feb 2023 12:23:14 +0000 Subject: [PATCH 35/55] 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> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 20477662e..62111fc9e 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.19 require ( github.com/ahmetalpbalkan/go-cursor v0.0.0-20131010032410-8136607ea412 github.com/blang/semver/v4 v4.0.0 - github.com/containers/image/v5 v5.24.0 + github.com/containers/image/v5 v5.24.1 github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2 github.com/fatih/color v1.14.1 github.com/go-logr/logr v1.2.3 diff --git a/go.sum b/go.sum index 2df86e533..e26c5b5b6 100644 --- a/go.sum +++ b/go.sum @@ -410,8 +410,8 @@ github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ github.com/containernetworking/cni v0.8.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= github.com/containernetworking/plugins v0.8.6/go.mod h1:qnw5mN19D8fIwkqW7oHHYDHVlzhJpcY6TQxn/fUyDDM= github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRDjeJr6FLK6vuiUwoH7P8= -github.com/containers/image/v5 v5.24.0 h1:2Pu8ztTntqNxteVN15bORCQnM8rfnbYuyKwUiiKUBuc= -github.com/containers/image/v5 v5.24.0/go.mod h1:oss5F6ssGQz8ZtC79oY+fuzYA3m3zBek9tq9gmhuvHc= +github.com/containers/image/v5 v5.24.1 h1:XaRw3FJmvZtI297uBVTJluUVH4AQJ//YpHviaOw0C4M= +github.com/containers/image/v5 v5.24.1/go.mod h1:oss5F6ssGQz8ZtC79oY+fuzYA3m3zBek9tq9gmhuvHc= github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 h1:Qzk5C6cYglewc+UyGf6lc8Mj2UaPTHy/iF2De0/77CA= github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY= github.com/containers/ocicrypt v1.0.1/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/C+bKAeWFIrc= From 70e2b1001dca44a371a554f5c23503e17e431baf Mon Sep 17 00:00:00 2001 From: Camila Macedo <7708031+camilamacedo86@users.noreply.github.com> Date: Wed, 22 Feb 2023 10:06:44 +0000 Subject: [PATCH 36/55] Update README to add link for the docs (#1022) Co-authored-by: Evans Mungai --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 9362450b1..ffae84f22 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ Replicated Troubleshoot is a framework for collecting, redacting, and analyzing Troubleshoot provides two CLI tools as kubectl plugins (using [Krew](https://krew.dev)): `kubectl preflight` and `kubectl support-bundle`. Preflight provides pre-installation cluster conformance testing and validation (preflight checks) and support-bundle provides post-installation troubleshooting and diagnostics (support bundles). +To know more about troubleshoot, please visit: https://troubleshoot.sh/ + ## Preflight Checks Preflight checks are an easy-to-run set of conformance tests that can be written to verify that specific requirements in a cluster are met. From a32407a5fd46d551a01899144c0145e23e3a86ce Mon Sep 17 00:00:00 2001 From: Evans Mungai Date: Fri, 24 Feb 2023 18:24:51 +0000 Subject: [PATCH 37/55] feat: use klog as the default logging library (#1008) --- Makefile | 4 +- cmd/analyze/cli/root.go | 13 +++--- cmd/collect/cli/root.go | 13 +++--- cmd/preflight/cli/root.go | 16 ++++---- cmd/troubleshoot/cli/analyze.go | 3 -- cmd/troubleshoot/cli/redact.go | 3 -- cmd/troubleshoot/cli/root.go | 23 +++++------ cmd/troubleshoot/cli/run.go | 18 ++++----- cmd/util/util.go | 5 ++- internal/traces/otel.go | 4 +- pkg/analyze/analyzer.go | 6 +-- pkg/analyze/download.go | 4 +- pkg/collect/ceph.go | 4 +- pkg/collect/collect.go | 1 + pkg/collect/copy_from_host.go | 6 +-- pkg/collect/logs.go | 4 +- pkg/collect/longhorn.go | 8 ++-- pkg/collect/redact.go | 4 +- pkg/collect/run_pod.go | 10 ++--- pkg/collect/runner.go | 6 +-- pkg/collect/sysctl.go | 4 +- pkg/logger/logger.go | 65 ++++++++++++++++++++++++------ pkg/preflight/analyze.go | 4 +- pkg/preflight/collect.go | 6 +-- pkg/redact/yaml.go | 4 +- pkg/supportbundle/collect.go | 8 ++-- pkg/supportbundle/load.go | 8 ++-- pkg/supportbundle/supportbundle.go | 3 +- 28 files changed, 144 insertions(+), 113 deletions(-) diff --git a/Makefile b/Makefile index 5d01bec23..8977e1d08 100644 --- a/Makefile +++ b/Makefile @@ -213,9 +213,9 @@ scan: ./ .PHONY: lint -lint: +lint: fmt vet golangci-lint run --new -c .golangci.yaml ${BUILDPATHS} .PHONY: lint-and-fix -lint-and-fix: +lint-and-fix: fmt vet golangci-lint run --new --fix -c .golangci.yaml ${BUILDPATHS} diff --git a/cmd/analyze/cli/root.go b/cmd/analyze/cli/root.go index 8dddc2202..9754351c8 100644 --- a/cmd/analyze/cli/root.go +++ b/cmd/analyze/cli/root.go @@ -4,7 +4,6 @@ import ( "os" "strings" - "github.com/go-logr/logr" "github.com/replicatedhq/troubleshoot/cmd/util" "github.com/replicatedhq/troubleshoot/pkg/k8sutil" "github.com/replicatedhq/troubleshoot/pkg/logger" @@ -24,13 +23,10 @@ func RootCmd() *cobra.Command { v := viper.GetViper() v.BindPFlags(cmd.Flags()) - if !v.GetBool("debug") { - klog.SetLogger(logr.Discard()) - } - logger.SetQuiet(v.GetBool("quiet")) + logger.SetupLogger(v) if err := util.StartProfiling(); err != nil { - logger.Printf("Failed to start profiling: %v", err) + klog.Errorf("Failed to start profiling: %v", err) } }, RunE: func(cmd *cobra.Command, args []string) error { @@ -40,7 +36,7 @@ func RootCmd() *cobra.Command { }, PostRun: func(cmd *cobra.Command, args []string) { if err := util.StopProfiling(); err != nil { - logger.Printf("Failed to stop profiling: %v", err) + klog.Errorf("Failed to stop profiling: %v", err) } }, } @@ -54,6 +50,9 @@ func RootCmd() *cobra.Command { viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_")) + // Initialize klog flags + logger.InitKlogFlags(cmd) + k8sutil.AddFlags(cmd.Flags()) // CPU and memory profiling flags diff --git a/cmd/collect/cli/root.go b/cmd/collect/cli/root.go index 2f6bdb4fd..7dc064008 100644 --- a/cmd/collect/cli/root.go +++ b/cmd/collect/cli/root.go @@ -4,7 +4,6 @@ import ( "os" "strings" - "github.com/go-logr/logr" "github.com/replicatedhq/troubleshoot/cmd/util" "github.com/replicatedhq/troubleshoot/pkg/k8sutil" "github.com/replicatedhq/troubleshoot/pkg/logger" @@ -24,23 +23,20 @@ func RootCmd() *cobra.Command { v := viper.GetViper() v.BindPFlags(cmd.Flags()) - if !v.GetBool("debug") { - klog.SetLogger(logr.Discard()) - } + logger.SetupLogger(v) if err := util.StartProfiling(); err != nil { - logger.Printf("Failed to start profiling: %v", err) + klog.Errorf("Failed to start profiling: %v", err) } }, RunE: func(cmd *cobra.Command, args []string) error { v := viper.GetViper() - logger.SetQuiet(v.GetBool("quiet")) return runCollect(v, args[0]) }, PostRun: func(cmd *cobra.Command, args []string) { if err := util.StopProfiling(); err != nil { - logger.Printf("Failed to stop profiling: %v", err) + klog.Errorf("Failed to stop profiling: %v", err) } }, } @@ -68,6 +64,9 @@ func RootCmd() *cobra.Command { k8sutil.AddFlags(cmd.Flags()) + // Initialize klog flags + logger.InitKlogFlags(cmd) + // CPU and memory profiling flags util.AddProfilingFlags(cmd) diff --git a/cmd/preflight/cli/root.go b/cmd/preflight/cli/root.go index 12d91c614..102bfd057 100644 --- a/cmd/preflight/cli/root.go +++ b/cmd/preflight/cli/root.go @@ -5,7 +5,6 @@ import ( "os" "strings" - "github.com/go-logr/logr" "github.com/replicatedhq/troubleshoot/cmd/util" "github.com/replicatedhq/troubleshoot/internal/traces" "github.com/replicatedhq/troubleshoot/pkg/k8sutil" @@ -29,12 +28,10 @@ that a cluster meets the requirements to run an application.`, v.SetEnvKeyReplacer(strings.NewReplacer("-", "_")) v.BindPFlags(cmd.Flags()) - if !v.GetBool("debug") { - klog.SetLogger(logr.Discard()) - } + logger.SetupLogger(v) if err := util.StartProfiling(); err != nil { - logger.Printf("Failed to start profiling: %v", err) + klog.Errorf("Failed to start profiling: %v", err) } }, RunE: func(cmd *cobra.Command, args []string) error { @@ -42,20 +39,20 @@ that a cluster meets the requirements to run an application.`, closer, err := traces.ConfigureTracing("preflight") if err != nil { // Do not fail running preflights if tracing fails - logger.Printf("Failed to initialize open tracing provider: %v", err) + klog.Errorf("Failed to initialize open tracing provider: %v", err) } else { defer closer() } err = preflight.RunPreflights(v.GetBool("interactive"), v.GetString("output"), v.GetString("format"), args) - if v.GetBool("debug") { + if v.GetBool("debug") || v.IsSet("v") { fmt.Printf("\n%s", traces.GetExporterInstance().GetSummary()) } return err }, PostRun: func(cmd *cobra.Command, args []string) { if err := util.StopProfiling(); err != nil { - logger.Printf("Failed to stop profiling: %v", err) + klog.Errorf("Failed to stop profiling: %v", err) } }, } @@ -67,6 +64,9 @@ that a cluster meets the requirements to run an application.`, k8sutil.AddFlags(cmd.Flags()) + // Initialize klog flags + logger.InitKlogFlags(cmd) + // CPU and memory profiling flags util.AddProfilingFlags(cmd) diff --git a/cmd/troubleshoot/cli/analyze.go b/cmd/troubleshoot/cli/analyze.go index bd2a11cd4..09adca194 100644 --- a/cmd/troubleshoot/cli/analyze.go +++ b/cmd/troubleshoot/cli/analyze.go @@ -10,7 +10,6 @@ import ( "github.com/replicatedhq/troubleshoot/cmd/util" analyzer "github.com/replicatedhq/troubleshoot/pkg/analyze" "github.com/replicatedhq/troubleshoot/pkg/convert" - "github.com/replicatedhq/troubleshoot/pkg/logger" "github.com/spf13/cobra" "github.com/spf13/viper" "gopkg.in/yaml.v2" @@ -28,8 +27,6 @@ func Analyze() *cobra.Command { RunE: func(cmd *cobra.Command, args []string) error { v := viper.GetViper() - logger.SetQuiet(v.GetBool("quiet")) - specPath := args[0] analyzerSpec, err := downloadAnalyzerSpec(specPath) if err != nil { diff --git a/cmd/troubleshoot/cli/redact.go b/cmd/troubleshoot/cli/redact.go index 4031a6705..8da57f807 100644 --- a/cmd/troubleshoot/cli/redact.go +++ b/cmd/troubleshoot/cli/redact.go @@ -8,7 +8,6 @@ import ( "github.com/pkg/errors" analyzer "github.com/replicatedhq/troubleshoot/pkg/analyze" "github.com/replicatedhq/troubleshoot/pkg/collect" - "github.com/replicatedhq/troubleshoot/pkg/logger" "github.com/replicatedhq/troubleshoot/pkg/supportbundle" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -35,8 +34,6 @@ For more information on redactors visit https://troubleshoot.sh/docs/redact/ RunE: func(cmd *cobra.Command, args []string) error { v := viper.GetViper() - logger.SetQuiet(v.GetBool("quiet")) - // 1. Decode redactors from provided URLs redactors, err := supportbundle.GetRedactorsFromURIs(args) if err != nil { diff --git a/cmd/troubleshoot/cli/root.go b/cmd/troubleshoot/cli/root.go index 0e52b4b64..14ec01438 100644 --- a/cmd/troubleshoot/cli/root.go +++ b/cmd/troubleshoot/cli/root.go @@ -5,7 +5,6 @@ import ( "os" "strings" - "github.com/go-logr/logr" "github.com/replicatedhq/troubleshoot/cmd/util" "github.com/replicatedhq/troubleshoot/internal/traces" "github.com/replicatedhq/troubleshoot/pkg/k8sutil" @@ -28,30 +27,25 @@ from a server that can be used to assist when troubleshooting a Kubernetes clust v.SetEnvKeyReplacer(strings.NewReplacer("-", "_")) v.BindPFlags(cmd.Flags()) + logger.SetupLogger(v) + if err := util.StartProfiling(); err != nil { - logger.Printf("Failed to start profiling: %v", err) + klog.Errorf("Failed to start profiling: %v", err) } }, - PreRun: func(cmd *cobra.Command, args []string) { - v := viper.GetViper() - if !v.GetBool("debug") { - klog.SetLogger(logr.Discard()) - } - logger.SetQuiet(!v.GetBool("debug")) - }, RunE: func(cmd *cobra.Command, args []string) error { v := viper.GetViper() closer, err := traces.ConfigureTracing("support-bundle") if err != nil { // Do not fail running support-bundle if tracing fails - logger.Printf("Failed to initialize open tracing provider: %v", err) + klog.Errorf("Failed to initialize open tracing provider: %v", err) } else { defer closer() } err = runTroubleshoot(v, args) - if v.GetBool("debug") { + if v.GetBool("debug") || v.IsSet("v") { fmt.Printf("\n%s", traces.GetExporterInstance().GetSummary()) } @@ -59,7 +53,7 @@ from a server that can be used to assist when troubleshooting a Kubernetes clust }, PersistentPostRun: func(cmd *cobra.Command, args []string) { if err := util.StopProfiling(); err != nil { - logger.Printf("Failed to stop profiling: %v", err) + klog.Errorf("Failed to stop profiling: %v", err) } }, } @@ -79,7 +73,7 @@ from a server that can be used to assist when troubleshooting a Kubernetes clust 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") + cmd.Flags().Bool("debug", false, "enable debug logging. This is equivalent to --v=0") // 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") @@ -91,6 +85,9 @@ from a server that can be used to assist when troubleshooting a Kubernetes clust k8sutil.AddFlags(cmd.Flags()) + // Initialize klog flags + logger.InitKlogFlags(cmd) + // CPU and memory profiling flags util.AddProfilingFlags(cmd) diff --git a/cmd/troubleshoot/cli/run.go b/cmd/troubleshoot/cli/run.go index c23cfeb3b..8d9244c41 100644 --- a/cmd/troubleshoot/cli/run.go +++ b/cmd/troubleshoot/cli/run.go @@ -23,7 +23,6 @@ import ( "github.com/replicatedhq/troubleshoot/pkg/convert" "github.com/replicatedhq/troubleshoot/pkg/httputil" "github.com/replicatedhq/troubleshoot/pkg/k8sutil" - "github.com/replicatedhq/troubleshoot/pkg/logger" "github.com/replicatedhq/troubleshoot/pkg/specs" "github.com/replicatedhq/troubleshoot/pkg/supportbundle" "github.com/spf13/viper" @@ -31,6 +30,7 @@ import ( "k8s.io/apimachinery/pkg/labels" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" + "k8s.io/klog/v2" ) func runTroubleshoot(v *viper.Viper, arg []string) error { @@ -134,13 +134,13 @@ func runTroubleshoot(v *viper.Viper, arg []string) error { // Search cluster for Troubleshoot objects in cluster bundlesFromSecrets, err := specs.LoadFromSecretMatchingLabel(client, parsedSelector.String(), namespace, specs.SupportBundleKey) if err != nil { - logger.Printf("failed to load support bundle spec from secrets: %s", err) + klog.Errorf("failed to load support bundle spec from secrets: %s", err) } bundlesFromCluster = append(bundlesFromCluster, bundlesFromSecrets...) bundlesFromConfigMaps, err := specs.LoadFromConfigMapMatchingLabel(client, parsedSelector.String(), namespace, specs.SupportBundleKey) if err != nil { - logger.Printf("failed to load support bundle spec from secrets: %s", err) + klog.Errorf("failed to load support bundle spec from secrets: %s", err) } bundlesFromCluster = append(bundlesFromCluster, bundlesFromConfigMaps...) @@ -148,7 +148,7 @@ func runTroubleshoot(v *viper.Viper, arg []string) error { multidocs := strings.Split(string(bundle), "\n---\n") parsedBundleFromSecret, err := supportbundle.ParseSupportBundleFromDoc([]byte(multidocs[0])) if err != nil { - logger.Printf("failed to parse support bundle spec: %s", err) + klog.Errorf("failed to parse support bundle spec: %s", err) continue } @@ -160,7 +160,7 @@ func runTroubleshoot(v *viper.Viper, arg []string) error { parsedRedactors, err := supportbundle.ParseRedactorsFromDocs(multidocs) if err != nil { - logger.Printf("failed to parse redactors from doc: %s", err) + klog.Errorf("failed to parse redactors from doc: %s", err) continue } @@ -172,13 +172,13 @@ func runTroubleshoot(v *viper.Viper, arg []string) error { // Search cluster for Troubleshoot objects in ConfigMaps redactorsFromSecrets, err := specs.LoadFromSecretMatchingLabel(client, parsedSelector.String(), namespace, specs.RedactorKey) if err != nil { - logger.Printf("failed to load redactor specs from config maps: %s", err) + klog.Errorf("failed to load redactor specs from config maps: %s", err) } redactorsFromCluster = append(redactorsFromCluster, redactorsFromSecrets...) redactorsFromConfigMaps, err := specs.LoadFromConfigMapMatchingLabel(client, parsedSelector.String(), namespace, specs.RedactorKey) if err != nil { - logger.Printf("failed to load redactor specs from config maps: %s", err) + klog.Errorf("failed to load redactor specs from config maps: %s", err) } redactorsFromCluster = append(redactorsFromCluster, redactorsFromConfigMaps...) @@ -186,7 +186,7 @@ func runTroubleshoot(v *viper.Viper, arg []string) error { multidocs := strings.Split(string(redactor), "\n---\n") parsedRedactors, err := supportbundle.ParseRedactorsFromDocs(multidocs) if err != nil { - logger.Printf("failed to parse redactors from doc: %s", err) + klog.Errorf("failed to parse redactors from doc: %s", err) } additionalRedactors.Spec.Redactors = append(additionalRedactors.Spec.Redactors, parsedRedactors...) @@ -229,7 +229,7 @@ func runTroubleshoot(v *viper.Viper, arg []string) error { go func() { defer wg.Done() for msg := range progressChan { - logger.Printf("Collecting support bundle: %v", msg) + klog.Infof("Collecting support bundle: %v", msg) } }() } else { diff --git a/cmd/util/util.go b/cmd/util/util.go index 3b83a2b6b..65207b5b6 100644 --- a/cmd/util/util.go +++ b/cmd/util/util.go @@ -4,6 +4,9 @@ import ( "net/url" "os" "strings" + + "golang.org/x/text/cases" + "golang.org/x/text/language" ) func HomeDir() string { @@ -23,7 +26,7 @@ func IsURL(str string) bool { } func AppName(name string) string { - words := strings.Split(strings.Title(strings.Replace(name, "-", " ", -1)), " ") + words := strings.Split(cases.Title(language.English).String(strings.ReplaceAll(name, "-", " ")), " ") casedWords := []string{} for i, word := range words { if strings.ToLower(word) == "ai" { diff --git a/internal/traces/otel.go b/internal/traces/otel.go index 01a201ea4..43628a5b5 100644 --- a/internal/traces/otel.go +++ b/internal/traces/otel.go @@ -3,13 +3,13 @@ package traces import ( "context" - "github.com/replicatedhq/troubleshoot/pkg/logger" "github.com/replicatedhq/troubleshoot/pkg/version" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/sdk/resource" "go.opentelemetry.io/otel/sdk/trace" semconv "go.opentelemetry.io/otel/semconv/v1.12.0" + "k8s.io/klog/v2" ) // ConfigureTracing configures the OpenTelemetry trace provider for CLI @@ -54,7 +54,7 @@ func ConfigureTracing(processName string) (func(), error) { return func() { if err := tp.Shutdown(context.Background()); err != nil { - logger.Printf("Failed to shutdown trace provider: %v", err) + klog.Errorf("Failed to shutdown trace provider: %v", err) } }, nil } diff --git a/pkg/analyze/analyzer.go b/pkg/analyze/analyzer.go index bfd91d661..517017aed 100644 --- a/pkg/analyze/analyzer.go +++ b/pkg/analyze/analyzer.go @@ -9,12 +9,12 @@ import ( "github.com/pkg/errors" troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" "github.com/replicatedhq/troubleshoot/pkg/constants" - "github.com/replicatedhq/troubleshoot/pkg/logger" "github.com/replicatedhq/troubleshoot/pkg/multitype" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" corev1 "k8s.io/api/core/v1" + "k8s.io/klog/v2" ) type AnalyzeResult struct { @@ -73,7 +73,7 @@ func HostAnalyze( isExcluded, _ := analyzer.IsExcluded() if isExcluded { - logger.Printf("Excluding %q analyzer", analyzer.Title()) + klog.Infof("excluding %q analyzer", analyzer.Title()) span.SetAttributes(attribute.Bool(constants.EXCLUDED, true)) return nil } @@ -511,7 +511,7 @@ func Analyze( return nil, err } if isExcluded { - logger.Printf("Excluding %q analyzer", analyzerInst.Title()) + klog.Infof("excluding %q analyzer", analyzerInst.Title()) span.SetAttributes(attribute.Bool(constants.EXCLUDED, true)) return nil, nil } diff --git a/pkg/analyze/download.go b/pkg/analyze/download.go index 2f7a19f22..0aeaadad5 100644 --- a/pkg/analyze/download.go +++ b/pkg/analyze/download.go @@ -15,9 +15,9 @@ import ( troubleshootscheme "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/scheme" "github.com/replicatedhq/troubleshoot/pkg/constants" "github.com/replicatedhq/troubleshoot/pkg/docrewrite" - "github.com/replicatedhq/troubleshoot/pkg/logger" "github.com/replicatedhq/troubleshoot/pkg/types" "k8s.io/client-go/kubernetes/scheme" + "k8s.io/klog/v2" ) type fileContentProvider struct { @@ -42,7 +42,7 @@ func AnalyzeLocal( for _, analyzer := range analyzers { analyzeResult, err := Analyze(ctx, analyzer, fcp.getFileContents, fcp.getChildFileContents) if err != nil { - logger.Printf("An analyzer failed to run: %v", err) + klog.Errorf("An analyzer failed to run: %v", err) continue } diff --git a/pkg/collect/ceph.go b/pkg/collect/ceph.go index e2a4234d9..901955a73 100644 --- a/pkg/collect/ceph.go +++ b/pkg/collect/ceph.go @@ -9,10 +9,10 @@ import ( "github.com/pkg/errors" troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" - "github.com/replicatedhq/troubleshoot/pkg/logger" corev1 "k8s.io/api/core/v1" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" + "k8s.io/klog/v2" ) const ( @@ -213,7 +213,7 @@ func findRookCephToolsPod(ctx context.Context, c *CollectCeph, namespace string) return &pods[0], nil } - logger.Printf("rook ceph tools pod not found") + klog.Info("rook ceph tools pod not found") return nil, nil } diff --git a/pkg/collect/collect.go b/pkg/collect/collect.go index 9cfdd4e15..d7d948751 100644 --- a/pkg/collect/collect.go +++ b/pkg/collect/collect.go @@ -71,6 +71,7 @@ func CollectHost(c *troubleshootv1beta2.HostCollector, additionalRedactors *trou for _, collector := range collectors { isExcluded, _ := collector.IsExcluded() if isExcluded { + opts.ProgressChan <- fmt.Sprintf("[%s] Excluding collector", collector.Title()) continue } diff --git a/pkg/collect/copy_from_host.go b/pkg/collect/copy_from_host.go index b4ecef1ae..4270d45de 100644 --- a/pkg/collect/copy_from_host.go +++ b/pkg/collect/copy_from_host.go @@ -12,7 +12,6 @@ import ( "github.com/pkg/errors" troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" "github.com/replicatedhq/troubleshoot/pkg/k8sutil" - "github.com/replicatedhq/troubleshoot/pkg/logger" "github.com/segmentio/ksuid" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" @@ -24,6 +23,7 @@ import ( "k8s.io/client-go/rest" restclient "k8s.io/client-go/rest" "k8s.io/client-go/tools/remotecommand" + "k8s.io/klog/v2" ) type CollectCopyFromHost struct { @@ -204,7 +204,7 @@ func copyFromHostCreateDaemonSet(ctx context.Context, client kubernetes.Interfac cleanupFuncs = append(cleanupFuncs, func() { err := client.CoreV1().Secrets(namespace).Delete(context.Background(), collector.ImagePullSecret.Name, metav1.DeleteOptions{}) if err != nil && !kuberneteserrors.IsNotFound(err) { - logger.Printf("Failed to delete secret %s: %v", collector.ImagePullSecret.Name, err) + klog.Errorf("Failed to delete secret %s: %v", collector.ImagePullSecret.Name, err) } }) } @@ -215,7 +215,7 @@ func copyFromHostCreateDaemonSet(ctx context.Context, client kubernetes.Interfac } cleanupFuncs = append(cleanupFuncs, func() { if err := client.AppsV1().DaemonSets(namespace).Delete(context.Background(), createdDS.Name, metav1.DeleteOptions{}); err != nil { - logger.Printf("Failed to delete daemonset %s: %v", createdDS.Name, err) + klog.Errorf("Failed to delete daemonset %s: %v", createdDS.Name, err) } }) diff --git a/pkg/collect/logs.go b/pkg/collect/logs.go index 666f42ec8..df5fc9383 100644 --- a/pkg/collect/logs.go +++ b/pkg/collect/logs.go @@ -11,11 +11,11 @@ import ( "github.com/pkg/errors" troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" "github.com/replicatedhq/troubleshoot/pkg/constants" - "github.com/replicatedhq/troubleshoot/pkg/logger" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" + "k8s.io/klog/v2" ) type CollectLogs struct { @@ -243,7 +243,7 @@ func savePodLogs( func convertMaxAgeToTime(maxAge string) *metav1.Time { parsedDuration, err := time.ParseDuration(maxAge) if err != nil { - logger.Printf("Failed to parse time duration %s", maxAge) + klog.Errorf("Failed to parse time duration %s", maxAge) return nil } diff --git a/pkg/collect/longhorn.go b/pkg/collect/longhorn.go index ffc70134b..45c525cbe 100644 --- a/pkg/collect/longhorn.go +++ b/pkg/collect/longhorn.go @@ -12,7 +12,6 @@ import ( "github.com/pkg/errors" troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" - "github.com/replicatedhq/troubleshoot/pkg/logger" longhornv1beta1types "github.com/replicatedhq/troubleshoot/pkg/longhorn/apis/longhorn/v1beta1" longhornv1beta1 "github.com/replicatedhq/troubleshoot/pkg/longhorn/client/clientset/versioned/typed/longhorn/v1beta1" longhorntypes "github.com/replicatedhq/troubleshoot/pkg/longhorn/types" @@ -22,6 +21,7 @@ import ( "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" "k8s.io/client-go/tools/remotecommand" + "k8s.io/klog/v2" ) const ( @@ -69,8 +69,8 @@ func (c *CollectLonghorn) Collect(progressChan chan<- interface{}) (CollectorRes if err != nil { if apiErr, ok := err.(*apiErrors.StatusError); ok { if apiErr.ErrStatus.Code == http.StatusNotFound { - logger.Printf("list nodes.longhorn.io not found") - return nil, nil + klog.Error("list nodes.longhorn.io not found") + return NewResult(), nil } } return nil, errors.Wrap(err, "list nodes.longhorn.io") @@ -280,7 +280,7 @@ func (c *CollectLonghorn) Collect(progressChan chan<- interface{}) (CollectorRes defer wg.Done() checksums, err := GetLonghornReplicaChecksum(c.ClientConfig, replica, podName) if err != nil { - logger.Printf("Failed to get replica %s checksum: %v", replica.Name, err) + klog.Errorf("Failed to get replica %s checksum: %v", replica.Name, err) return } volsDir := GetLonghornVolumesDirectory(ns) diff --git a/pkg/collect/redact.go b/pkg/collect/redact.go index aa6b027e5..e9fdd74b0 100644 --- a/pkg/collect/redact.go +++ b/pkg/collect/redact.go @@ -49,9 +49,9 @@ func RedactResult(bundlePath string, input CollectorResult, additionalRedactors if err != nil { return errors.Wrap(err, "failed to get relative path") } - klog.V(4).Infof("Redacting %s (symlink => %s)\n", file, symlink) + klog.V(2).Infof("Redacting %s (symlink => %s)\n", file, symlink) } else { - klog.V(4).Infof("Redacting %s\n", file) + klog.V(2).Infof("Redacting %s\n", file) } r, err := input.GetReader(bundlePath, file) if err != nil { diff --git a/pkg/collect/run_pod.go b/pkg/collect/run_pod.go index 37c3308d6..9f5a2a980 100644 --- a/pkg/collect/run_pod.go +++ b/pkg/collect/run_pod.go @@ -12,11 +12,11 @@ import ( "github.com/pkg/errors" troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" "github.com/replicatedhq/troubleshoot/pkg/k8sutil" - "github.com/replicatedhq/troubleshoot/pkg/logger" corev1 "k8s.io/api/core/v1" "k8s.io/client-go/kubernetes" v1 "k8s.io/client-go/kubernetes/typed/core/v1" "k8s.io/client-go/rest" + "k8s.io/klog/v2" kuberneteserrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -54,7 +54,7 @@ func (c *CollectRunPod) Collect(progressChan chan<- interface{}) (CollectorResul } defer func() { if err := client.CoreV1().Pods(pod.Namespace).Delete(context.Background(), pod.Name, metav1.DeleteOptions{}); err != nil { - logger.Printf("Failed to delete pod %s: %v", pod.Name, err) + klog.Errorf("Failed to delete pod %s: %v", pod.Name, err) } }() @@ -62,7 +62,7 @@ func (c *CollectRunPod) Collect(progressChan chan<- interface{}) (CollectorResul defer func() { for _, k := range pod.Spec.ImagePullSecrets { if err := client.CoreV1().Secrets(pod.Namespace).Delete(context.Background(), k.Name, metav1.DeleteOptions{}); err != nil { - logger.Printf("Failed to delete secret %s: %v", k.Name, err) + klog.Errorf("Failed to delete secret %s: %v", k.Name, err) } } }() @@ -316,7 +316,7 @@ func RunPodsReadyNodes(ctx context.Context, client v1.CoreV1Interface, opts RunP } logs, err := RunPodLogs(ctx, client, pod) if err != nil { - logger.Printf("Failed to run pod on node %s: %v", node, err) + klog.Errorf("Failed to run pod on node %s: %v", node, err) return } @@ -341,7 +341,7 @@ func RunPodLogs(ctx context.Context, client v1.CoreV1Interface, podSpec *corev1. defer func() { err := client.Pods(pod.Namespace).Delete(context.Background(), pod.Name, metav1.DeleteOptions{}) if err != nil && !kuberneteserrors.IsNotFound(err) { - logger.Printf("Failed to delete pod %s: %v\n", pod.Name, err) + klog.Errorf("Failed to delete pod %s: %v\n", pod.Name, err) } }() diff --git a/pkg/collect/runner.go b/pkg/collect/runner.go index ae47c43cd..30ce9388b 100644 --- a/pkg/collect/runner.go +++ b/pkg/collect/runner.go @@ -10,7 +10,6 @@ import ( "github.com/pkg/errors" troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" - "github.com/replicatedhq/troubleshoot/pkg/logger" corev1 "k8s.io/api/core/v1" kerrors "k8s.io/apimachinery/pkg/api/errors" kuberneteserrors "k8s.io/apimachinery/pkg/api/errors" @@ -18,6 +17,7 @@ import ( runtime "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/kubernetes" "k8s.io/client-go/util/retry" + "k8s.io/klog/v2" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" ) @@ -43,10 +43,10 @@ func (r *podRunner) run(ctx context.Context, collector *troubleshootv1beta2.Host defer func() { if err := r.client.CoreV1().Pods(namespace).Delete(context.Background(), pod.Name, metav1.DeleteOptions{}); err != nil { - logger.Printf("Failed to delete pod %s: %v\n", pod.Name, err) + klog.Errorf("Failed to delete pod %s: %v\n", pod.Name, err) } if err := r.client.CoreV1().ConfigMaps(namespace).Delete(context.Background(), cm.Name, metav1.DeleteOptions{}); err != nil { - logger.Printf("Failed to delete configmap %s: %v\n", pod.Name, err) + klog.Errorf("Failed to delete configmap %s: %v\n", pod.Name, err) } }() diff --git a/pkg/collect/sysctl.go b/pkg/collect/sysctl.go index ef36012e7..b93721061 100644 --- a/pkg/collect/sysctl.go +++ b/pkg/collect/sysctl.go @@ -9,11 +9,11 @@ import ( "github.com/pkg/errors" troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" "github.com/replicatedhq/troubleshoot/pkg/k8sutil" - "github.com/replicatedhq/troubleshoot/pkg/logger" kuberneteserrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" + "k8s.io/klog/v2" ) type CollectSysctl struct { @@ -82,7 +82,7 @@ find /proc/sys/vm -type f | while read f; do v=$(cat $f 2>/dev/null); echo "$f = defer func() { err := c.Client.CoreV1().Secrets(c.Collector.Namespace).Delete(context.Background(), c.Collector.ImagePullSecret.Name, metav1.DeleteOptions{}) if err != nil && !kuberneteserrors.IsNotFound(err) { - logger.Printf("Failed to delete secret %s: %v", c.Collector.ImagePullSecret.Name, err) + klog.Errorf("Failed to delete secret %s: %v", c.Collector.ImagePullSecret.Name, err) } }() diff --git a/pkg/logger/logger.go b/pkg/logger/logger.go index 44acf7fdc..dcbd4f366 100644 --- a/pkg/logger/logger.go +++ b/pkg/logger/logger.go @@ -1,26 +1,65 @@ +/* +Logging library for the troubleshoot framework. + +Logging levels +TODO: Document me here => https://github.com/replicatedhq/troubleshoot/issues/1031 + +0: also the same as not using V() log progress related information within the framework. Logs within each component (collector/analyzers/etc) should not use this level. + +1: High level logs within each component (collector/analyzers/etc) should use this level. A log such as "Ceph collector connected to the cluster" belongs here. + +2: Everything else goes here. If you do not know which level to use, use this level. + +The best approach is to always use V(2) then after testing your code as a whole, you can elevate the log level of the messages you find useful to V(1) or V(0). + +Do not log errors in functions that return an error. Instead, return the error and let the caller log it. +*/ package logger import ( - "log" - "os" -) + "flag" + "sync" -var ( - logger *log.Logger - quiet = false + "github.com/go-logr/logr" + "github.com/spf13/cobra" + "github.com/spf13/viper" + "k8s.io/klog/v2" ) -func init() { - logger = log.New(os.Stderr, "", log.LstdFlags) +var lock sync.Mutex + +// InitKlogFlags initializes klog flags and adds them to the cobra command. +func InitKlogFlags(cmd *cobra.Command) { + // Initialize klog flags + klogFlags := flag.NewFlagSet("klog", flag.ExitOnError) + klog.InitFlags(klogFlags) + + klogFlags.VisitAll(func(f *flag.Flag) { + // Just the flags we want to expose in our CLI + if f.Name == "v" { + // If we ever want to expose the klog flags that have underscores ("_") in them + // we need to replace them with hyphens ("-") in the flag name using + // pflag.NormalizedName(strings.ReplaceAll(name, "_", "-")). Check how kubectl does it + cmd.Flags().AddGoFlag(f) + } + }) } -func SetQuiet(s bool) { - quiet = s +// SetupLogger sets up klog logger based on viper configuration. +func SetupLogger(v *viper.Viper) { + quiet := v.GetBool("debug") || v.IsSet("v") + SetQuiet(!quiet) } -func Printf(format string, args ...interface{}) { +// SetQuiet enables or disables klog logger. +func SetQuiet(quiet bool) { + lock.Lock() + defer lock.Unlock() + if quiet { - return + klog.SetLogger(logr.Discard()) + } else { + // Restore the default logger + klog.ClearLogger() } - logger.Printf(format, args...) } diff --git a/pkg/preflight/analyze.go b/pkg/preflight/analyze.go index 9edb5bc34..cb0903525 100644 --- a/pkg/preflight/analyze.go +++ b/pkg/preflight/analyze.go @@ -9,7 +9,7 @@ import ( analyze "github.com/replicatedhq/troubleshoot/pkg/analyze" troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" - "github.com/replicatedhq/troubleshoot/pkg/logger" + "k8s.io/klog/v2" ) // Analyze runs the analyze phase of preflight checks @@ -100,7 +100,7 @@ func doAnalyze( if err != nil { strict, strictErr := HasStrictAnalyzer(analyzer) if strictErr != nil { - logger.Printf("failed to determine if analyzer %v is strict: %s", analyzer, strictErr) + klog.Errorf("failed to determine if analyzer %v is strict: %s", analyzer, strictErr) } analyzeResult = []*analyze.AnalyzeResult{ diff --git a/pkg/preflight/collect.go b/pkg/preflight/collect.go index fbcbbc1eb..cfdadc1ae 100644 --- a/pkg/preflight/collect.go +++ b/pkg/preflight/collect.go @@ -12,13 +12,13 @@ import ( troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" "github.com/replicatedhq/troubleshoot/pkg/collect" "github.com/replicatedhq/troubleshoot/pkg/constants" - "github.com/replicatedhq/troubleshoot/pkg/logger" "github.com/replicatedhq/troubleshoot/pkg/version" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" + "k8s.io/klog/v2" ) type CollectOpts struct { @@ -123,7 +123,7 @@ func CollectHostWithContext( isExcluded, _ := collector.IsExcluded() if isExcluded { - logger.Printf("Excluding %q collector", collector.Title()) + opts.ProgressChan <- fmt.Sprintf("[%s] Excluding collector", collector.Title()) span.SetAttributes(attribute.Bool(constants.EXCLUDED, true)) span.End() continue @@ -236,7 +236,7 @@ func CollectWithContext(ctx context.Context, opts CollectOpts, p *troubleshootv1 isExcluded, _ := collector.IsExcluded() if isExcluded { - logger.Printf("Excluding %q collector", collector.Title()) + klog.Infof("excluding %q collector", collector.Title()) span.SetAttributes(attribute.Bool(constants.EXCLUDED, true)) span.End() continue diff --git a/pkg/redact/yaml.go b/pkg/redact/yaml.go index 1c8d9e893..02ff43647 100644 --- a/pkg/redact/yaml.go +++ b/pkg/redact/yaml.go @@ -9,8 +9,8 @@ import ( "strconv" "strings" - "github.com/replicatedhq/troubleshoot/pkg/logger" "gopkg.in/yaml.v2" + "k8s.io/klog/v2" ) type YamlRedactor struct { @@ -30,7 +30,7 @@ func (r *YamlRedactor) Redact(input io.Reader, path string) io.Reader { if r.filePath != "" { match, err := filepath.Match(r.filePath, path) if err != nil { - logger.Printf("Failed to match %q and %q: %v", r.filePath, path, err) + klog.Errorf("Failed to match %q and %q: %v", r.filePath, path, err) return input } if !match { diff --git a/pkg/supportbundle/collect.go b/pkg/supportbundle/collect.go index 9971aa6e7..60c8cb868 100644 --- a/pkg/supportbundle/collect.go +++ b/pkg/supportbundle/collect.go @@ -15,7 +15,6 @@ import ( "github.com/replicatedhq/troubleshoot/pkg/collect" "github.com/replicatedhq/troubleshoot/pkg/constants" "github.com/replicatedhq/troubleshoot/pkg/convert" - "github.com/replicatedhq/troubleshoot/pkg/logger" "github.com/replicatedhq/troubleshoot/pkg/version" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" @@ -45,7 +44,7 @@ func runHostCollectors(ctx context.Context, hostCollectors []*troubleshootv1beta isExcluded, _ := collector.IsExcluded() if isExcluded { - logger.Printf("Excluding %q collector", collector.Title()) + opts.ProgressChan <- fmt.Sprintf("[%s] Excluding host collector", collector.Title()) span.SetAttributes(attribute.Bool(constants.EXCLUDED, true)) span.End() continue @@ -152,7 +151,8 @@ func runCollectors(ctx context.Context, collectors []*troubleshootv1beta2.Collec isExcluded, _ := collector.IsExcluded() if isExcluded { - logger.Printf("Excluding %q collector", collector.Title()) + msg := fmt.Sprintf("excluding %q collector", collector.Title()) + opts.CollectorProgressCallback(opts.ProgressChan, msg) span.SetAttributes(attribute.Bool(constants.EXCLUDED, true)) span.End() continue @@ -161,7 +161,7 @@ func runCollectors(ctx context.Context, collectors []*troubleshootv1beta2.Collec // skip collectors with RBAC errors unless its the ClusterResources collector if collector.HasRBACErrors() { if _, ok := collector.(*collect.CollectClusterResources); !ok { - msg := fmt.Sprintf("skipping collector %s with insufficient RBAC permissions", collector.Title()) + msg := fmt.Sprintf("skipping collector %q with insufficient RBAC permissions", collector.Title()) opts.CollectorProgressCallback(opts.ProgressChan, msg) span.SetStatus(codes.Error, "skipping collector, insufficient RBAC permissions") span.End() diff --git a/pkg/supportbundle/load.go b/pkg/supportbundle/load.go index 65988f73c..b04185f98 100644 --- a/pkg/supportbundle/load.go +++ b/pkg/supportbundle/load.go @@ -15,10 +15,10 @@ import ( troubleshootclientsetscheme "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/scheme" "github.com/replicatedhq/troubleshoot/pkg/docrewrite" "github.com/replicatedhq/troubleshoot/pkg/httputil" - "github.com/replicatedhq/troubleshoot/pkg/logger" "github.com/replicatedhq/troubleshoot/pkg/oci" "github.com/replicatedhq/troubleshoot/pkg/specs" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/klog/v2" ) func GetSupportBundleFromURI(bundleURI string) (*troubleshootv1beta2.SupportBundle, error) { @@ -78,10 +78,10 @@ func ParseSupportBundle(doc []byte, followURI bool) (*troubleshootv1beta2.Suppor // use the upstream spec, otherwise fall back to // what's defined in the current spec if supportBundle.Spec.Uri != "" && followURI { - logger.Printf("using upstream reference: %+v\n", supportBundle.Spec.Uri) + klog.Infof("using upstream reference: %+v\n", supportBundle.Spec.Uri) upstreamSupportBundleContent, err := LoadSupportBundleSpec(supportBundle.Spec.Uri) if err != nil { - logger.Printf("failed to load upstream supportbundle, falling back") + klog.Errorf("failed to load upstream supportbundle, falling back") return supportBundle, nil } @@ -89,7 +89,7 @@ func ParseSupportBundle(doc []byte, followURI bool) (*troubleshootv1beta2.Suppor upstreamSupportBundle, err := ParseSupportBundle([]byte(multidocs[0]), false) if err != nil { - logger.Printf("failed to parse upstream supportbundle, falling back") + klog.Errorf("failed to parse upstream supportbundle, falling back") return supportBundle, nil } return upstreamSupportBundle, nil diff --git a/pkg/supportbundle/supportbundle.go b/pkg/supportbundle/supportbundle.go index e68eb7c72..9783b9234 100644 --- a/pkg/supportbundle/supportbundle.go +++ b/pkg/supportbundle/supportbundle.go @@ -19,7 +19,6 @@ import ( "github.com/replicatedhq/troubleshoot/pkg/collect" "github.com/replicatedhq/troubleshoot/pkg/constants" "github.com/replicatedhq/troubleshoot/pkg/convert" - "github.com/replicatedhq/troubleshoot/pkg/logger" "go.opentelemetry.io/otel" "k8s.io/client-go/rest" "k8s.io/klog/v2" @@ -181,7 +180,7 @@ func CollectSupportBundleFromSpec( err = result.SaveResult(bundlePath, "execution-data/summary.txt", bytes.NewReader([]byte(summary))) if err != nil { // Don't fail the support bundle if we can't save the execution summary - logger.Printf("failed to save execution summary file in the support bundle: %v", err) + klog.Errorf("failed to save execution summary file in the support bundle: %v", err) } // Archive Support Bundle From aa4620a8b621031cc2a7fb68f67ed75a8baf2ff5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Mar 2023 11:52:22 +0000 Subject: [PATCH 38/55] 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> --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 62111fc9e..07faf431f 100644 --- a/go.mod +++ b/go.mod @@ -27,12 +27,12 @@ require ( github.com/pkg/errors v0.9.1 github.com/replicatedhq/termui/v3 v3.1.1-0.20200811145416-f40076d26851 github.com/segmentio/ksuid v1.0.4 - github.com/shirou/gopsutil/v3 v3.23.1 + github.com/shirou/gopsutil/v3 v3.23.2 github.com/sirupsen/logrus v1.9.0 github.com/spf13/cobra v1.6.1 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.15.0 - github.com/stretchr/testify v1.8.1 + github.com/stretchr/testify v1.8.2 github.com/tj/go-spin v1.1.0 go.opentelemetry.io/otel v1.13.0 go.opentelemetry.io/otel/sdk v1.13.0 diff --git a/go.sum b/go.sum index e26c5b5b6..41ccedfdc 100644 --- a/go.sum +++ b/go.sum @@ -1103,8 +1103,8 @@ github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c= github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= -github.com/shirou/gopsutil/v3 v3.23.1 h1:a9KKO+kGLKEvcPIs4W62v0nu3sciVDOOOPUD0Hz7z/4= -github.com/shirou/gopsutil/v3 v3.23.1/go.mod h1:NN6mnm5/0k8jw4cBfCnJtr5L7ErOTg18tMNpgFkn0hA= +github.com/shirou/gopsutil/v3 v3.23.2 h1:PAWSuiAszn7IhPMBtXsbSCafej7PqUOvY6YywlQUExU= +github.com/shirou/gopsutil/v3 v3.23.2/go.mod h1:gv0aQw33GLo3pG8SiWKiQrbDzbRY1K80RyZJ7V4Th1M= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= @@ -1163,8 +1163,9 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/sylabs/sif/v2 v2.9.0 h1:q9K92j1QW4/QLOtKh9YZpJHrXav6x15AVhQGPVLcg+4= @@ -1558,7 +1559,6 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= From 65e163d9206bb71d585baf5738f288c5c9ff6bcf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Mar 2023 13:44:07 +0000 Subject: [PATCH 39/55] 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> --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 07faf431f..8afc08d73 100644 --- a/go.mod +++ b/go.mod @@ -34,7 +34,7 @@ require ( github.com/spf13/viper v1.15.0 github.com/stretchr/testify v1.8.2 github.com/tj/go-spin v1.1.0 - go.opentelemetry.io/otel v1.13.0 + go.opentelemetry.io/otel v1.14.0 go.opentelemetry.io/otel/sdk v1.13.0 golang.org/x/sync v0.1.0 gopkg.in/yaml.v2 v2.4.0 @@ -67,7 +67,7 @@ require ( github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sylabs/sif/v2 v2.9.0 // indirect - go.opentelemetry.io/otel/trace v1.13.0 // indirect + go.opentelemetry.io/otel/trace v1.14.0 // indirect golang.org/x/mod v0.7.0 // indirect golang.org/x/tools v0.4.0 // indirect ) diff --git a/go.sum b/go.sum index 41ccedfdc..d3dcdb3fb 100644 --- a/go.sum +++ b/go.sum @@ -1244,12 +1244,12 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/otel v1.13.0 h1:1ZAKnNQKwBBxFtww/GwxNUyTf0AxkZzrukO8MeXqe4Y= -go.opentelemetry.io/otel v1.13.0/go.mod h1:FH3RtdZCzRkJYFTCsAKDy9l/XYjMdNv6QrkFFB8DvVg= +go.opentelemetry.io/otel v1.14.0 h1:/79Huy8wbf5DnIPhemGB+zEPVwnN6fuQybr/SRXa6hM= +go.opentelemetry.io/otel v1.14.0/go.mod h1:o4buv+dJzx8rohcUeRmWUZhqupFvzWis188WlggnNeU= go.opentelemetry.io/otel/sdk v1.13.0 h1:BHib5g8MvdqS65yo2vV1s6Le42Hm6rrw08qU6yz5JaM= go.opentelemetry.io/otel/sdk v1.13.0/go.mod h1:YLKPx5+6Vx/o1TCUYYs+bpymtkmazOMT6zoRrC7AQ7I= -go.opentelemetry.io/otel/trace v1.13.0 h1:CBgRZ6ntv+Amuj1jDsMhZtlAPT6gbyIRdaIzFhfBSdY= -go.opentelemetry.io/otel/trace v1.13.0/go.mod h1:muCvmmO9KKpvuXSf3KKAXXB2ygNYHQ+ZfI5X08d3tds= +go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M= +go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 h1:+FNtrFTmVw0YZGpBGX56XDee331t6JAXeK2bcyhLOOc= go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o= From 6a70342db098b15973b4090b86bda4ceff681d59 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Mar 2023 13:44:43 +0000 Subject: [PATCH 40/55] 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> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 8afc08d73..0c7ccf0ff 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.19 require ( github.com/ahmetalpbalkan/go-cursor v0.0.0-20131010032410-8136607ea412 github.com/blang/semver/v4 v4.0.0 - github.com/containers/image/v5 v5.24.1 + github.com/containers/image/v5 v5.24.2 github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2 github.com/fatih/color v1.14.1 github.com/go-logr/logr v1.2.3 diff --git a/go.sum b/go.sum index d3dcdb3fb..8a098876b 100644 --- a/go.sum +++ b/go.sum @@ -410,8 +410,8 @@ github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ github.com/containernetworking/cni v0.8.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= github.com/containernetworking/plugins v0.8.6/go.mod h1:qnw5mN19D8fIwkqW7oHHYDHVlzhJpcY6TQxn/fUyDDM= github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRDjeJr6FLK6vuiUwoH7P8= -github.com/containers/image/v5 v5.24.1 h1:XaRw3FJmvZtI297uBVTJluUVH4AQJ//YpHviaOw0C4M= -github.com/containers/image/v5 v5.24.1/go.mod h1:oss5F6ssGQz8ZtC79oY+fuzYA3m3zBek9tq9gmhuvHc= +github.com/containers/image/v5 v5.24.2 h1:QcMsHBAXBPPnVYo6iEFarvaIpym7sBlwsGHPJlucxN0= +github.com/containers/image/v5 v5.24.2/go.mod h1:oss5F6ssGQz8ZtC79oY+fuzYA3m3zBek9tq9gmhuvHc= github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 h1:Qzk5C6cYglewc+UyGf6lc8Mj2UaPTHy/iF2De0/77CA= github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY= github.com/containers/ocicrypt v1.0.1/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/C+bKAeWFIrc= From c3c01f7ae47c3a735d6c8f38a92e34cb9c334e9a Mon Sep 17 00:00:00 2001 From: Ethan Mosbaugh Date: Wed, 8 Mar 2023 06:29:16 -0800 Subject: [PATCH 41/55] feat: support for rhel 9 variants (rhel, centos, ol, rocky) (#1045) --- .../crds/troubleshoot.sh_hostcollectors.yaml | 24 +++++++ .../crds/troubleshoot.sh_hostpreflights.yaml | 24 +++++++ .../crds/troubleshoot.sh_supportbundles.yaml | 24 +++++++ examples/preflight/host/system-packages.yaml | 14 ++++ .../v1beta2/hostcollector_shared.go | 6 ++ .../v1beta2/zz_generated.deepcopy.go | 30 ++++++++ pkg/client/troubleshootclientset/clientset.go | 44 +++++++++--- .../v1beta1/fake/fake_analyzer.go | 2 +- .../v1beta1/fake/fake_collector.go | 2 +- .../v1beta1/fake/fake_preflight.go | 2 +- .../v1beta1/fake/fake_redactor.go | 2 +- .../v1beta1/fake/fake_supportbundle.go | 2 +- .../v1beta1/troubleshoot_client.go | 20 +++++- .../v1beta2/fake/fake_analyzer.go | 2 +- .../v1beta2/fake/fake_collector.go | 2 +- .../v1beta2/fake/fake_hostcollector.go | 2 +- .../v1beta2/fake/fake_hostpreflight.go | 2 +- .../v1beta2/fake/fake_preflight.go | 2 +- .../v1beta2/fake/fake_redactor.go | 2 +- .../v1beta2/fake/fake_remotecollector.go | 2 +- .../v1beta2/fake/fake_supportbundle.go | 2 +- .../v1beta2/troubleshoot_client.go | 20 +++++- pkg/collect/host_block_device.go | 42 +++++++---- pkg/collect/host_block_device_test.go | 70 +++++++++++++++++++ pkg/collect/host_system_package.go | 21 +++++- .../supportbundle-troubleshoot-v1beta2.json | 36 ++++++++++ 26 files changed, 361 insertions(+), 40 deletions(-) create mode 100644 pkg/collect/host_block_device_test.go diff --git a/config/crds/troubleshoot.sh_hostcollectors.yaml b/config/crds/troubleshoot.sh_hostcollectors.yaml index df2bfe634..0cebd9150 100644 --- a/config/crds/troubleshoot.sh_hostcollectors.yaml +++ b/config/crds/troubleshoot.sh_hostcollectors.yaml @@ -1198,6 +1198,10 @@ spec: items: type: string type: array + centos9: + items: + type: string + type: array collectorName: type: string exclude: @@ -1214,6 +1218,10 @@ spec: items: type: string type: array + ol9: + items: + type: string + type: array rhel: items: type: string @@ -1226,6 +1234,22 @@ spec: items: type: string type: array + rhel9: + items: + type: string + type: array + rocky: + items: + type: string + type: array + rocky8: + items: + type: string + type: array + rocky9: + items: + type: string + type: array ubuntu: items: type: string diff --git a/config/crds/troubleshoot.sh_hostpreflights.yaml b/config/crds/troubleshoot.sh_hostpreflights.yaml index 5725cbd31..1cbc92442 100644 --- a/config/crds/troubleshoot.sh_hostpreflights.yaml +++ b/config/crds/troubleshoot.sh_hostpreflights.yaml @@ -1198,6 +1198,10 @@ spec: items: type: string type: array + centos9: + items: + type: string + type: array collectorName: type: string exclude: @@ -1214,6 +1218,10 @@ spec: items: type: string type: array + ol9: + items: + type: string + type: array rhel: items: type: string @@ -1226,6 +1234,22 @@ spec: items: type: string type: array + rhel9: + items: + type: string + type: array + rocky: + items: + type: string + type: array + rocky8: + items: + type: string + type: array + rocky9: + items: + type: string + type: array ubuntu: items: type: string diff --git a/config/crds/troubleshoot.sh_supportbundles.yaml b/config/crds/troubleshoot.sh_supportbundles.yaml index 2a03311dd..b126c30cb 100644 --- a/config/crds/troubleshoot.sh_supportbundles.yaml +++ b/config/crds/troubleshoot.sh_supportbundles.yaml @@ -11218,6 +11218,10 @@ spec: items: type: string type: array + centos9: + items: + type: string + type: array collectorName: type: string exclude: @@ -11234,6 +11238,10 @@ spec: items: type: string type: array + ol9: + items: + type: string + type: array rhel: items: type: string @@ -11246,6 +11254,22 @@ spec: items: type: string type: array + rhel9: + items: + type: string + type: array + rocky: + items: + type: string + type: array + rocky8: + items: + type: string + type: array + rocky9: + items: + type: string + type: array ubuntu: items: type: string diff --git a/examples/preflight/host/system-packages.yaml b/examples/preflight/host/system-packages.yaml index fe8e413f1..dd7f4f8c7 100644 --- a/examples/preflight/host/system-packages.yaml +++ b/examples/preflight/host/system-packages.yaml @@ -21,6 +21,15 @@ spec: rhel8: - nfs-utils - openssl + rhel9: + - nfs-utils + - openssl + rocky8: + - nfs-utils + - openssl + rocky9: + - nfs-utils + - openssl centos: - iscsi-initiator-utils centos7: @@ -28,6 +37,9 @@ spec: centos8: - nfs-utils - openssl + centos9: + - nfs-utils + - openssl ol: - lvm2 ol7: @@ -35,6 +47,8 @@ spec: - openssl ol8: - nfs-utils + ol9: + - nfs-utils amzn: - libzstd amzn2: diff --git a/pkg/apis/troubleshoot/v1beta2/hostcollector_shared.go b/pkg/apis/troubleshoot/v1beta2/hostcollector_shared.go index d3ee8cceb..0086ca0d6 100644 --- a/pkg/apis/troubleshoot/v1beta2/hostcollector_shared.go +++ b/pkg/apis/troubleshoot/v1beta2/hostcollector_shared.go @@ -82,12 +82,18 @@ type HostSystemPackages struct { RHEL []string `json:"rhel,omitempty"` RHEL7 []string `json:"rhel7,omitempty"` RHEL8 []string `json:"rhel8,omitempty"` + RHEL9 []string `json:"rhel9,omitempty"` + RockyLinux []string `json:"rocky,omitempty"` + RockyLinux8 []string `json:"rocky8,omitempty"` + RockyLinux9 []string `json:"rocky9,omitempty"` CentOS []string `json:"centos,omitempty"` CentOS7 []string `json:"centos7,omitempty"` CentOS8 []string `json:"centos8,omitempty"` + CentOS9 []string `json:"centos9,omitempty"` OracleLinux []string `json:"ol,omitempty"` OracleLinux7 []string `json:"ol7,omitempty"` OracleLinux8 []string `json:"ol8,omitempty"` + OracleLinux9 []string `json:"ol9,omitempty"` AmazonLinux []string `json:"amzn,omitempty"` AmazonLinux2 []string `json:"amzn2,omitempty"` } diff --git a/pkg/apis/troubleshoot/v1beta2/zz_generated.deepcopy.go b/pkg/apis/troubleshoot/v1beta2/zz_generated.deepcopy.go index 87a87e3dd..b60403379 100644 --- a/pkg/apis/troubleshoot/v1beta2/zz_generated.deepcopy.go +++ b/pkg/apis/troubleshoot/v1beta2/zz_generated.deepcopy.go @@ -2168,6 +2168,26 @@ func (in *HostSystemPackages) DeepCopyInto(out *HostSystemPackages) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.RHEL9 != nil { + in, out := &in.RHEL9, &out.RHEL9 + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.RockyLinux != nil { + in, out := &in.RockyLinux, &out.RockyLinux + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.RockyLinux8 != nil { + in, out := &in.RockyLinux8, &out.RockyLinux8 + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.RockyLinux9 != nil { + in, out := &in.RockyLinux9, &out.RockyLinux9 + *out = make([]string, len(*in)) + copy(*out, *in) + } if in.CentOS != nil { in, out := &in.CentOS, &out.CentOS *out = make([]string, len(*in)) @@ -2183,6 +2203,11 @@ func (in *HostSystemPackages) DeepCopyInto(out *HostSystemPackages) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.CentOS9 != nil { + in, out := &in.CentOS9, &out.CentOS9 + *out = make([]string, len(*in)) + copy(*out, *in) + } if in.OracleLinux != nil { in, out := &in.OracleLinux, &out.OracleLinux *out = make([]string, len(*in)) @@ -2198,6 +2223,11 @@ func (in *HostSystemPackages) DeepCopyInto(out *HostSystemPackages) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.OracleLinux9 != nil { + in, out := &in.OracleLinux9, &out.OracleLinux9 + *out = make([]string, len(*in)) + copy(*out, *in) + } if in.AmazonLinux != nil { in, out := &in.AmazonLinux, &out.AmazonLinux *out = make([]string, len(*in)) diff --git a/pkg/client/troubleshootclientset/clientset.go b/pkg/client/troubleshootclientset/clientset.go index cc5a29168..7af52d4d1 100644 --- a/pkg/client/troubleshootclientset/clientset.go +++ b/pkg/client/troubleshootclientset/clientset.go @@ -19,6 +19,7 @@ package troubleshootclientset import ( "fmt" + "net/http" troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1" troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2" @@ -33,8 +34,7 @@ type Interface interface { TroubleshootV1beta2() troubleshootv1beta2.TroubleshootV1beta2Interface } -// Clientset contains the clients for groups. Each group has exactly one -// version included in a Clientset. +// Clientset contains the clients for groups. type Clientset struct { *discovery.DiscoveryClient troubleshootV1beta1 *troubleshootv1beta1.TroubleshootV1beta1Client @@ -62,26 +62,49 @@ func (c *Clientset) Discovery() discovery.DiscoveryInterface { // NewForConfig creates a new Clientset for the given config. // If config's RateLimiter is not set and QPS and Burst are acceptable, // NewForConfig will generate a rate-limiter in configShallowCopy. +// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), +// where httpClient was generated with rest.HTTPClientFor(c). func NewForConfig(c *rest.Config) (*Clientset, error) { configShallowCopy := *c + + if configShallowCopy.UserAgent == "" { + configShallowCopy.UserAgent = rest.DefaultKubernetesUserAgent() + } + + // share the transport between all clients + httpClient, err := rest.HTTPClientFor(&configShallowCopy) + if err != nil { + return nil, err + } + + return NewForConfigAndClient(&configShallowCopy, httpClient) +} + +// NewForConfigAndClient creates a new Clientset for the given config and http client. +// Note the http client provided takes precedence over the configured transport values. +// If config's RateLimiter is not set and QPS and Burst are acceptable, +// NewForConfigAndClient will generate a rate-limiter in configShallowCopy. +func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset, error) { + configShallowCopy := *c if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 { if configShallowCopy.Burst <= 0 { return nil, fmt.Errorf("burst is required to be greater than 0 when RateLimiter is not set and QPS is set to greater than 0") } configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst) } + var cs Clientset var err error - cs.troubleshootV1beta1, err = troubleshootv1beta1.NewForConfig(&configShallowCopy) + cs.troubleshootV1beta1, err = troubleshootv1beta1.NewForConfigAndClient(&configShallowCopy, httpClient) if err != nil { return nil, err } - cs.troubleshootV1beta2, err = troubleshootv1beta2.NewForConfig(&configShallowCopy) + cs.troubleshootV1beta2, err = troubleshootv1beta2.NewForConfigAndClient(&configShallowCopy, httpClient) if err != nil { return nil, err } - cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfig(&configShallowCopy) + cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfigAndClient(&configShallowCopy, httpClient) if err != nil { return nil, err } @@ -91,12 +114,11 @@ func NewForConfig(c *rest.Config) (*Clientset, error) { // NewForConfigOrDie creates a new Clientset for the given config and // panics if there is an error in the config. func NewForConfigOrDie(c *rest.Config) *Clientset { - var cs Clientset - cs.troubleshootV1beta1 = troubleshootv1beta1.NewForConfigOrDie(c) - cs.troubleshootV1beta2 = troubleshootv1beta2.NewForConfigOrDie(c) - - cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c) - return &cs + cs, err := NewForConfig(c) + if err != nil { + panic(err) + } + return cs } // New creates a new Clientset for the given RESTClient. diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_analyzer.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_analyzer.go index ec5667589..2661cb460 100644 --- a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_analyzer.go +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_analyzer.go @@ -116,7 +116,7 @@ func (c *FakeAnalyzers) UpdateStatus(ctx context.Context, analyzer *v1beta1.Anal // Delete takes name of the analyzer and deletes it. Returns an error if one occurs. func (c *FakeAnalyzers) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteAction(analyzersResource, c.ns, name), &v1beta1.Analyzer{}) + Invokes(testing.NewDeleteActionWithOptions(analyzersResource, c.ns, name, opts), &v1beta1.Analyzer{}) return err } diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_collector.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_collector.go index 8ea3d5ec1..2a43591ed 100644 --- a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_collector.go +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_collector.go @@ -116,7 +116,7 @@ func (c *FakeCollectors) UpdateStatus(ctx context.Context, collector *v1beta1.Co // Delete takes name of the collector and deletes it. Returns an error if one occurs. func (c *FakeCollectors) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteAction(collectorsResource, c.ns, name), &v1beta1.Collector{}) + Invokes(testing.NewDeleteActionWithOptions(collectorsResource, c.ns, name, opts), &v1beta1.Collector{}) return err } diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_preflight.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_preflight.go index 9e2724708..35ddc41a8 100644 --- a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_preflight.go +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_preflight.go @@ -116,7 +116,7 @@ func (c *FakePreflights) UpdateStatus(ctx context.Context, preflight *v1beta1.Pr // Delete takes name of the preflight and deletes it. Returns an error if one occurs. func (c *FakePreflights) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteAction(preflightsResource, c.ns, name), &v1beta1.Preflight{}) + Invokes(testing.NewDeleteActionWithOptions(preflightsResource, c.ns, name, opts), &v1beta1.Preflight{}) return err } diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_redactor.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_redactor.go index 3109c7980..261d5dd49 100644 --- a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_redactor.go +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_redactor.go @@ -116,7 +116,7 @@ func (c *FakeRedactors) UpdateStatus(ctx context.Context, redactor *v1beta1.Reda // Delete takes name of the redactor and deletes it. Returns an error if one occurs. func (c *FakeRedactors) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteAction(redactorsResource, c.ns, name), &v1beta1.Redactor{}) + Invokes(testing.NewDeleteActionWithOptions(redactorsResource, c.ns, name, opts), &v1beta1.Redactor{}) return err } diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_supportbundle.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_supportbundle.go index 6b4b8e495..46d6b3a26 100644 --- a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_supportbundle.go +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_supportbundle.go @@ -116,7 +116,7 @@ func (c *FakeSupportBundles) UpdateStatus(ctx context.Context, supportBundle *v1 // Delete takes name of the supportBundle and deletes it. Returns an error if one occurs. func (c *FakeSupportBundles) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteAction(supportbundlesResource, c.ns, name), &v1beta1.SupportBundle{}) + Invokes(testing.NewDeleteActionWithOptions(supportbundlesResource, c.ns, name, opts), &v1beta1.SupportBundle{}) return err } diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/troubleshoot_client.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/troubleshoot_client.go index 8b5b3299b..628b5ebc2 100644 --- a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/troubleshoot_client.go +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/troubleshoot_client.go @@ -18,6 +18,8 @@ limitations under the License. package v1beta1 import ( + "net/http" + v1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/scheme" rest "k8s.io/client-go/rest" @@ -58,12 +60,28 @@ func (c *TroubleshootV1beta1Client) SupportBundles(namespace string) SupportBund } // NewForConfig creates a new TroubleshootV1beta1Client for the given config. +// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), +// where httpClient was generated with rest.HTTPClientFor(c). func NewForConfig(c *rest.Config) (*TroubleshootV1beta1Client, error) { config := *c if err := setConfigDefaults(&config); err != nil { return nil, err } - client, err := rest.RESTClientFor(&config) + httpClient, err := rest.HTTPClientFor(&config) + if err != nil { + return nil, err + } + return NewForConfigAndClient(&config, httpClient) +} + +// NewForConfigAndClient creates a new TroubleshootV1beta1Client for the given config and http client. +// Note the http client provided takes precedence over the configured transport values. +func NewForConfigAndClient(c *rest.Config, h *http.Client) (*TroubleshootV1beta1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + client, err := rest.RESTClientForConfigAndClient(&config, h) if err != nil { return nil, err } diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_analyzer.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_analyzer.go index b17f45840..c15c4745e 100644 --- a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_analyzer.go +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_analyzer.go @@ -116,7 +116,7 @@ func (c *FakeAnalyzers) UpdateStatus(ctx context.Context, analyzer *v1beta2.Anal // Delete takes name of the analyzer and deletes it. Returns an error if one occurs. func (c *FakeAnalyzers) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteAction(analyzersResource, c.ns, name), &v1beta2.Analyzer{}) + Invokes(testing.NewDeleteActionWithOptions(analyzersResource, c.ns, name, opts), &v1beta2.Analyzer{}) return err } diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_collector.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_collector.go index d352dd092..1f9c0053a 100644 --- a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_collector.go +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_collector.go @@ -116,7 +116,7 @@ func (c *FakeCollectors) UpdateStatus(ctx context.Context, collector *v1beta2.Co // Delete takes name of the collector and deletes it. Returns an error if one occurs. func (c *FakeCollectors) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteAction(collectorsResource, c.ns, name), &v1beta2.Collector{}) + Invokes(testing.NewDeleteActionWithOptions(collectorsResource, c.ns, name, opts), &v1beta2.Collector{}) return err } diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_hostcollector.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_hostcollector.go index 837c7576d..cd9d1b6a2 100644 --- a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_hostcollector.go +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_hostcollector.go @@ -116,7 +116,7 @@ func (c *FakeHostCollectors) UpdateStatus(ctx context.Context, hostCollector *v1 // Delete takes name of the hostCollector and deletes it. Returns an error if one occurs. func (c *FakeHostCollectors) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteAction(hostcollectorsResource, c.ns, name), &v1beta2.HostCollector{}) + Invokes(testing.NewDeleteActionWithOptions(hostcollectorsResource, c.ns, name, opts), &v1beta2.HostCollector{}) return err } diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_hostpreflight.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_hostpreflight.go index 761fd6d8c..57e5b9071 100644 --- a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_hostpreflight.go +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_hostpreflight.go @@ -116,7 +116,7 @@ func (c *FakeHostPreflights) UpdateStatus(ctx context.Context, hostPreflight *v1 // Delete takes name of the hostPreflight and deletes it. Returns an error if one occurs. func (c *FakeHostPreflights) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteAction(hostpreflightsResource, c.ns, name), &v1beta2.HostPreflight{}) + Invokes(testing.NewDeleteActionWithOptions(hostpreflightsResource, c.ns, name, opts), &v1beta2.HostPreflight{}) return err } diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_preflight.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_preflight.go index 67ee46668..a4014d75d 100644 --- a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_preflight.go +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_preflight.go @@ -116,7 +116,7 @@ func (c *FakePreflights) UpdateStatus(ctx context.Context, preflight *v1beta2.Pr // Delete takes name of the preflight and deletes it. Returns an error if one occurs. func (c *FakePreflights) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteAction(preflightsResource, c.ns, name), &v1beta2.Preflight{}) + Invokes(testing.NewDeleteActionWithOptions(preflightsResource, c.ns, name, opts), &v1beta2.Preflight{}) return err } diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_redactor.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_redactor.go index 433496600..3bfbf5fa2 100644 --- a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_redactor.go +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_redactor.go @@ -116,7 +116,7 @@ func (c *FakeRedactors) UpdateStatus(ctx context.Context, redactor *v1beta2.Reda // Delete takes name of the redactor and deletes it. Returns an error if one occurs. func (c *FakeRedactors) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteAction(redactorsResource, c.ns, name), &v1beta2.Redactor{}) + Invokes(testing.NewDeleteActionWithOptions(redactorsResource, c.ns, name, opts), &v1beta2.Redactor{}) return err } diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_remotecollector.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_remotecollector.go index ae0ddb17d..a9bcadf88 100644 --- a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_remotecollector.go +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_remotecollector.go @@ -116,7 +116,7 @@ func (c *FakeRemoteCollectors) UpdateStatus(ctx context.Context, remoteCollector // Delete takes name of the remoteCollector and deletes it. Returns an error if one occurs. func (c *FakeRemoteCollectors) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteAction(remotecollectorsResource, c.ns, name), &v1beta2.RemoteCollector{}) + Invokes(testing.NewDeleteActionWithOptions(remotecollectorsResource, c.ns, name, opts), &v1beta2.RemoteCollector{}) return err } diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_supportbundle.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_supportbundle.go index e5cb8ad8f..e71c0cfab 100644 --- a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_supportbundle.go +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/fake/fake_supportbundle.go @@ -116,7 +116,7 @@ func (c *FakeSupportBundles) UpdateStatus(ctx context.Context, supportBundle *v1 // Delete takes name of the supportBundle and deletes it. Returns an error if one occurs. func (c *FakeSupportBundles) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteAction(supportbundlesResource, c.ns, name), &v1beta2.SupportBundle{}) + Invokes(testing.NewDeleteActionWithOptions(supportbundlesResource, c.ns, name, opts), &v1beta2.SupportBundle{}) return err } diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/troubleshoot_client.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/troubleshoot_client.go index 6c3a0fea8..ae137af92 100644 --- a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/troubleshoot_client.go +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta2/troubleshoot_client.go @@ -18,6 +18,8 @@ limitations under the License. package v1beta2 import ( + "net/http" + v1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/scheme" rest "k8s.io/client-go/rest" @@ -73,12 +75,28 @@ func (c *TroubleshootV1beta2Client) SupportBundles(namespace string) SupportBund } // NewForConfig creates a new TroubleshootV1beta2Client for the given config. +// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), +// where httpClient was generated with rest.HTTPClientFor(c). func NewForConfig(c *rest.Config) (*TroubleshootV1beta2Client, error) { config := *c if err := setConfigDefaults(&config); err != nil { return nil, err } - client, err := rest.RESTClientFor(&config) + httpClient, err := rest.HTTPClientFor(&config) + if err != nil { + return nil, err + } + return NewForConfigAndClient(&config, httpClient) +} + +// NewForConfigAndClient creates a new TroubleshootV1beta2Client for the given config and http client. +// Note the http client provided takes precedence over the configured transport values. +func NewForConfigAndClient(c *rest.Config, h *http.Client) (*TroubleshootV1beta2Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + client, err := rest.RESTClientForConfigAndClient(&config, h) if err != nil { return nil, err } diff --git a/pkg/collect/host_block_device.go b/pkg/collect/host_block_device.go index fc24834e0..b6e553c1c 100644 --- a/pkg/collect/host_block_device.go +++ b/pkg/collect/host_block_device.go @@ -6,6 +6,7 @@ import ( "encoding/json" "fmt" "os/exec" + "strings" "github.com/pkg/errors" troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" @@ -44,22 +45,43 @@ func (c *CollectHostBlockDevices) IsExcluded() (bool, error) { } func (c *CollectHostBlockDevices) Collect(progressChan chan<- interface{}) (map[string][]byte, error) { - var devices []BlockDeviceInfo - cmd := exec.Command("lsblk", "--noheadings", "--bytes", "--pairs", "-o", lsblkColumns) stdout, err := cmd.Output() if err != nil { return nil, errors.Wrapf(err, "failed to execute lsblk") } - buf := bytes.NewBuffer(stdout) + + devices, err := parseLsblkOutput(stdout) + if err != nil { + return nil, errors.Wrap(err, "failed to parse block device output") + } + + b, err := json.Marshal(devices) + if err != nil { + return nil, errors.Wrap(err, "failed to marshal block device info") + } + + output := NewResult() + output.SaveResult(c.BundlePath, HostBlockDevicesPath, bytes.NewBuffer(b)) + + return map[string][]byte{ + HostBlockDevicesPath: b, + }, nil +} + +func parseLsblkOutput(output []byte) ([]BlockDeviceInfo, error) { + var devices []BlockDeviceInfo + + buf := bytes.NewBuffer(output) scanner := bufio.NewScanner(buf) for scanner.Scan() { bdi := BlockDeviceInfo{} var ro int var rm int + line := strings.ReplaceAll(scanner.Text(), "MAJ_MIN", "MAJ:MIN") fmt.Sscanf( - scanner.Text(), + line, lsblkFormat, &bdi.Name, &bdi.KernelName, @@ -80,15 +102,9 @@ func (c *CollectHostBlockDevices) Collect(progressChan chan<- interface{}) (map[ devices = append(devices, bdi) } - b, err := json.Marshal(devices) - if err != nil { - return nil, errors.Wrap(err, "failed to marshal block device info") + if err := scanner.Err(); err != nil { + return nil, errors.Wrap(err, "failed to scan lsblk output") } - output := NewResult() - output.SaveResult(c.BundlePath, HostBlockDevicesPath, bytes.NewBuffer(b)) - - return map[string][]byte{ - HostBlockDevicesPath: b, - }, nil + return devices, nil } diff --git a/pkg/collect/host_block_device_test.go b/pkg/collect/host_block_device_test.go new file mode 100644 index 000000000..72180cb9f --- /dev/null +++ b/pkg/collect/host_block_device_test.go @@ -0,0 +1,70 @@ +package collect + +import ( + "reflect" + "testing" +) + +func Test_parseLsblkDeviceOutput(t *testing.T) { + tests := []struct { + name string + output []byte + want []BlockDeviceInfo + wantErr bool + }{ + { + name: "ubuntu 20.04", + output: []byte(`NAME="sdb" KNAME="sdb" PKNAME="" TYPE="disk" MAJ:MIN="8:16" SIZE="107374182400" FSTYPE="" MOUNTPOINT="" SERIAL="persistent-disk-1" RO="0" RM="0"`), + want: []BlockDeviceInfo{ + { + Name: "sdb", + KernelName: "sdb", + ParentKernelName: "", + Type: "disk", + Major: 8, + Minor: 16, + Size: 107374182400, + FilesystemType: "", + Mountpoint: "", + Serial: "persistent-disk-1", + ReadOnly: false, + Removable: false, + }, + }, + wantErr: false, + }, + { + name: "rhel 9", + output: []byte(`NAME="sdb" KNAME="sdb" PKNAME="" TYPE="disk" MAJ_MIN="8:16" SIZE="107374182400" FSTYPE="" MOUNTPOINT="" SERIAL="persistent-disk-1" RO="0" RM="0"`), + want: []BlockDeviceInfo{ + { + Name: "sdb", + KernelName: "sdb", + ParentKernelName: "", + Type: "disk", + Major: 8, + Minor: 16, + Size: 107374182400, + FilesystemType: "", + Mountpoint: "", + Serial: "persistent-disk-1", + ReadOnly: false, + Removable: false, + }, + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := parseLsblkOutput(tt.output) + if (err != nil) != tt.wantErr { + t.Errorf("parseLsblkOutput() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("parseLsblkOutput() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/collect/host_system_package.go b/pkg/collect/host_system_package.go index a7c0d3f05..ef073a1a3 100644 --- a/pkg/collect/host_system_package.go +++ b/pkg/collect/host_system_package.go @@ -92,6 +92,9 @@ func (c *CollectHostSystemPackages) Collect(progressChan chan<- interface{}) (ma if len(c.hostCollector.CentOS8) > 0 && matchMajorVersion(info.OSVersion, "8") { packages = append(packages, c.hostCollector.CentOS8...) } + if len(c.hostCollector.CentOS9) > 0 && matchMajorVersion(info.OSVersion, "9") { + packages = append(packages, c.hostCollector.CentOS8...) + } case "rhel": if len(c.hostCollector.RHEL) > 0 { packages = append(packages, c.hostCollector.RHEL...) @@ -102,6 +105,9 @@ func (c *CollectHostSystemPackages) Collect(progressChan chan<- interface{}) (ma if len(c.hostCollector.RHEL8) > 0 && matchMajorVersion(info.OSVersion, "8") { packages = append(packages, c.hostCollector.RHEL8...) } + if len(c.hostCollector.RHEL9) > 0 && matchMajorVersion(info.OSVersion, "9") { + packages = append(packages, c.hostCollector.RHEL9...) + } case "ol": if len(c.hostCollector.OracleLinux) > 0 { packages = append(packages, c.hostCollector.OracleLinux...) @@ -112,6 +118,19 @@ func (c *CollectHostSystemPackages) Collect(progressChan chan<- interface{}) (ma if len(c.hostCollector.OracleLinux8) > 0 && matchMajorVersion(info.OSVersion, "8") { packages = append(packages, c.hostCollector.OracleLinux8...) } + if len(c.hostCollector.OracleLinux9) > 0 && matchMajorVersion(info.OSVersion, "9") { + packages = append(packages, c.hostCollector.OracleLinux9...) + } + case "rocky": + if len(c.hostCollector.RockyLinux) > 0 { + packages = append(packages, c.hostCollector.RockyLinux...) + } + if len(c.hostCollector.RockyLinux8) > 0 && matchMajorVersion(info.OSVersion, "8") { + packages = append(packages, c.hostCollector.RockyLinux8...) + } + if len(c.hostCollector.RockyLinux9) > 0 && matchMajorVersion(info.OSVersion, "9") { + packages = append(packages, c.hostCollector.RockyLinux9...) + } case "amzn": if len(c.hostCollector.AmazonLinux) > 0 { packages = append(packages, c.hostCollector.AmazonLinux...) @@ -132,7 +151,7 @@ func (c *CollectHostSystemPackages) Collect(progressChan chan<- interface{}) (ma switch info.OS { case "ubuntu": cmd = exec.Command("dpkg", "-s", p) - case "centos", "rhel", "amzn", "ol": + case "centos", "rhel", "amzn", "ol", "rocky": cmd = exec.Command("rpm", "-qi", p) default: return nil, errors.Errorf("unsupported distribution: %s", info.OS) diff --git a/schemas/supportbundle-troubleshoot-v1beta2.json b/schemas/supportbundle-troubleshoot-v1beta2.json index 15b6ed2cb..35bccafcc 100644 --- a/schemas/supportbundle-troubleshoot-v1beta2.json +++ b/schemas/supportbundle-troubleshoot-v1beta2.json @@ -10938,6 +10938,12 @@ "type": "string" } }, + "centos9": { + "type": "array", + "items": { + "type": "string" + } + }, "collectorName": { "type": "string" }, @@ -10962,6 +10968,12 @@ "type": "string" } }, + "ol9": { + "type": "array", + "items": { + "type": "string" + } + }, "rhel": { "type": "array", "items": { @@ -10980,6 +10992,30 @@ "type": "string" } }, + "rhel9": { + "type": "array", + "items": { + "type": "string" + } + }, + "rocky": { + "type": "array", + "items": { + "type": "string" + } + }, + "rocky8": { + "type": "array", + "items": { + "type": "string" + } + }, + "rocky9": { + "type": "array", + "items": { + "type": "string" + } + }, "ubuntu": { "type": "array", "items": { From 316844cd19146dbe4709bd04dc9031771e671cd5 Mon Sep 17 00:00:00 2001 From: Diamon Wiggins <38189728+diamonwiggins@users.noreply.github.com> Date: Wed, 8 Mar 2023 11:33:27 -0400 Subject: [PATCH 42/55] fix: Use namespace from the collector spec for Ceph (#1042) use namespace from the collector spec for ceph --- pkg/collect/ceph.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/collect/ceph.go b/pkg/collect/ceph.go index 901955a73..3815bcda4 100644 --- a/pkg/collect/ceph.go +++ b/pkg/collect/ceph.go @@ -128,11 +128,11 @@ func (c *CollectCeph) IsExcluded() (bool, error) { func (c *CollectCeph) Collect(progressChan chan<- interface{}) (CollectorResult, error) { ctx := context.TODO() - if c.Namespace == "" { - c.Namespace = DefaultCephNamespace + if c.Collector.Namespace == "" { + c.Collector.Namespace = DefaultCephNamespace } - pod, err := findRookCephToolsPod(ctx, c, c.Namespace) + pod, err := findRookCephToolsPod(ctx, c, c.Collector.Namespace) if err != nil { return nil, err } @@ -142,7 +142,7 @@ func (c *CollectCeph) Collect(progressChan chan<- interface{}) (CollectorResult, for _, command := range CephCommands { err := cephCommandExec(ctx, progressChan, c, c.Collector, pod, command, output) if err != nil { - pathPrefix := GetCephCollectorFilepath(c.Collector.CollectorName, c.Namespace) + pathPrefix := GetCephCollectorFilepath(c.Collector.CollectorName, c.Collector.Namespace) dstFileName := path.Join(pathPrefix, fmt.Sprintf("%s.%s-error", command.ID, command.Format)) output.SaveResult(c.BundlePath, dstFileName, strings.NewReader(err.Error())) } From 627b33b22b3bfaf904988320320f258b7f681f00 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Mar 2023 14:22:18 +0000 Subject: [PATCH 43/55] 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> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 0c7ccf0ff..dae2482ca 100644 --- a/go.mod +++ b/go.mod @@ -35,7 +35,7 @@ require ( github.com/stretchr/testify v1.8.2 github.com/tj/go-spin v1.1.0 go.opentelemetry.io/otel v1.14.0 - go.opentelemetry.io/otel/sdk v1.13.0 + go.opentelemetry.io/otel/sdk v1.14.0 golang.org/x/sync v0.1.0 gopkg.in/yaml.v2 v2.4.0 k8s.io/api v0.26.1 diff --git a/go.sum b/go.sum index 8a098876b..6a163348a 100644 --- a/go.sum +++ b/go.sum @@ -1246,8 +1246,8 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/otel v1.14.0 h1:/79Huy8wbf5DnIPhemGB+zEPVwnN6fuQybr/SRXa6hM= go.opentelemetry.io/otel v1.14.0/go.mod h1:o4buv+dJzx8rohcUeRmWUZhqupFvzWis188WlggnNeU= -go.opentelemetry.io/otel/sdk v1.13.0 h1:BHib5g8MvdqS65yo2vV1s6Le42Hm6rrw08qU6yz5JaM= -go.opentelemetry.io/otel/sdk v1.13.0/go.mod h1:YLKPx5+6Vx/o1TCUYYs+bpymtkmazOMT6zoRrC7AQ7I= +go.opentelemetry.io/otel/sdk v1.14.0 h1:PDCppFRDq8A1jL9v6KMI6dYesaq+DFcDZvjsoGvxGzY= +go.opentelemetry.io/otel/sdk v1.14.0/go.mod h1:bwIC5TjrNG6QDCHNWvW4HLHtUQ4I+VQDsnjhvyZCALM= go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M= go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= From bf6afb8ae2d0ff5739f545c80dbcce7ff828db45 Mon Sep 17 00:00:00 2001 From: Nathan Sullivan Date: Fri, 10 Mar 2023 12:52:21 +1000 Subject: [PATCH 44/55] 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. --- config/crds/troubleshoot.sh_analyzers.yaml | 49 +++ .../crds/troubleshoot.sh_hostcollectors.yaml | 63 ++++ .../crds/troubleshoot.sh_hostpreflights.yaml | 77 +++++ config/crds/troubleshoot.sh_preflights.yaml | 14 + .../troubleshoot.sh_remotecollectors.yaml | 14 + .../crds/troubleshoot.sh_supportbundles.yaml | 63 ++++ examples/preflight/host/subnet-available.yaml | 19 ++ go.mod | 1 + go.sum | 2 + pkg/analyze/host_analyzer.go | 2 + pkg/analyze/host_subnetavailable.go | 82 ++++++ .../v1beta2/hostanalyzer_shared.go | 8 + .../v1beta2/hostcollector_shared.go | 7 + .../v1beta2/remote_collector_shared.go | 7 + .../v1beta2/zz_generated.deepcopy.go | 74 +++++ pkg/collect/host_collector.go | 2 + pkg/collect/host_subnetavailable.go | 278 ++++++++++++++++++ pkg/collect/host_subnetavailable_test.go | 203 +++++++++++++ pkg/collect/remote_collector.go | 7 + schemas/analyzer-troubleshoot-v1beta2.json | 76 +++++ schemas/preflight-troubleshoot-v1beta2.json | 21 ++ .../supportbundle-troubleshoot-v1beta2.json | 97 ++++++ 22 files changed, 1166 insertions(+) create mode 100644 examples/preflight/host/subnet-available.yaml create mode 100644 pkg/analyze/host_subnetavailable.go create mode 100644 pkg/collect/host_subnetavailable.go create mode 100644 pkg/collect/host_subnetavailable_test.go diff --git a/config/crds/troubleshoot.sh_analyzers.yaml b/config/crds/troubleshoot.sh_analyzers.yaml index f5b77a777..fa5b592c4 100644 --- a/config/crds/troubleshoot.sh_analyzers.yaml +++ b/config/crds/troubleshoot.sh_analyzers.yaml @@ -2108,6 +2108,55 @@ spec: required: - outcomes type: object + subnetAvailable: + 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: diff --git a/config/crds/troubleshoot.sh_hostcollectors.yaml b/config/crds/troubleshoot.sh_hostcollectors.yaml index 0cebd9150..980e0c70e 100644 --- a/config/crds/troubleshoot.sh_hostcollectors.yaml +++ b/config/crds/troubleshoot.sh_hostcollectors.yaml @@ -633,6 +633,55 @@ spec: required: - outcomes type: object + subnetAvailable: + 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: @@ -1176,6 +1225,20 @@ spec: - args - command type: object + subnetAvailable: + properties: + CIDRRangeAlloc: + type: string + collectorName: + type: string + desiredCIDR: + type: integer + exclude: + type: BoolString + required: + - CIDRRangeAlloc + - desiredCIDR + type: object systemPackages: properties: amzn: diff --git a/config/crds/troubleshoot.sh_hostpreflights.yaml b/config/crds/troubleshoot.sh_hostpreflights.yaml index 1cbc92442..54d6aea6c 100644 --- a/config/crds/troubleshoot.sh_hostpreflights.yaml +++ b/config/crds/troubleshoot.sh_hostpreflights.yaml @@ -633,6 +633,55 @@ spec: required: - outcomes type: object + subnetAvailable: + 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: @@ -1176,6 +1225,20 @@ spec: - args - command type: object + subnetAvailable: + properties: + CIDRRangeAlloc: + type: string + collectorName: + type: string + desiredCIDR: + type: integer + exclude: + type: BoolString + required: + - CIDRRangeAlloc + - desiredCIDR + type: object systemPackages: properties: amzn: @@ -1548,6 +1611,20 @@ spec: exclude: type: BoolString type: object + subnetAvailable: + properties: + CIDRRangeAlloc: + type: string + collectorName: + type: string + desiredCIDR: + type: integer + exclude: + type: BoolString + required: + - CIDRRangeAlloc + - desiredCIDR + type: object systemPackages: properties: collectorName: diff --git a/config/crds/troubleshoot.sh_preflights.yaml b/config/crds/troubleshoot.sh_preflights.yaml index 89c5cc3a8..4de7299dd 100644 --- a/config/crds/troubleshoot.sh_preflights.yaml +++ b/config/crds/troubleshoot.sh_preflights.yaml @@ -10241,6 +10241,20 @@ spec: exclude: type: BoolString type: object + subnetAvailable: + properties: + CIDRRangeAlloc: + type: string + collectorName: + type: string + desiredCIDR: + type: integer + exclude: + type: BoolString + required: + - CIDRRangeAlloc + - desiredCIDR + type: object systemPackages: properties: collectorName: diff --git a/config/crds/troubleshoot.sh_remotecollectors.yaml b/config/crds/troubleshoot.sh_remotecollectors.yaml index 6a20532a9..7f4f89685 100644 --- a/config/crds/troubleshoot.sh_remotecollectors.yaml +++ b/config/crds/troubleshoot.sh_remotecollectors.yaml @@ -283,6 +283,20 @@ spec: exclude: type: BoolString type: object + subnetAvailable: + properties: + CIDRRangeAlloc: + type: string + collectorName: + type: string + desiredCIDR: + type: integer + exclude: + type: BoolString + required: + - CIDRRangeAlloc + - desiredCIDR + type: object systemPackages: properties: collectorName: diff --git a/config/crds/troubleshoot.sh_supportbundles.yaml b/config/crds/troubleshoot.sh_supportbundles.yaml index b126c30cb..0fab2af31 100644 --- a/config/crds/troubleshoot.sh_supportbundles.yaml +++ b/config/crds/troubleshoot.sh_supportbundles.yaml @@ -10653,6 +10653,55 @@ spec: required: - outcomes type: object + subnetAvailable: + 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: @@ -11196,6 +11245,20 @@ spec: - args - command type: object + subnetAvailable: + properties: + CIDRRangeAlloc: + type: string + collectorName: + type: string + desiredCIDR: + type: integer + exclude: + type: BoolString + required: + - CIDRRangeAlloc + - desiredCIDR + type: object systemPackages: properties: amzn: diff --git a/examples/preflight/host/subnet-available.yaml b/examples/preflight/host/subnet-available.yaml new file mode 100644 index 000000000..34fb1c7f7 --- /dev/null +++ b/examples/preflight/host/subnet-available.yaml @@ -0,0 +1,19 @@ +apiVersion: troubleshoot.sh/v1beta2 +kind: HostPreflight +metadata: + name: subnet-available +spec: + collectors: + # would output yes/no depending if there is a /22 available in 10.0.0.0/8 + - subnetAvailable: + CIDRRangeAlloc: "10.0.0.0/8" + desiredCIDR: 22 + analyzers: + - subnetAvailable: + outcomes: + - fail: + when: "no-subnet-available" + message: failed to find available subnet + - pass: + when: "a-subnet-is-available" + message: available /22 subnet found diff --git a/go.mod b/go.mod index dae2482ca..90d62fbd9 100644 --- a/go.mod +++ b/go.mod @@ -51,6 +51,7 @@ require ( require ( cloud.google.com/go/compute/metadata v0.2.3 // indirect + github.com/apparentlymart/go-cidr v1.1.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/docker/distribution v2.8.1+incompatible // indirect github.com/emicklei/go-restful/v3 v3.9.0 // indirect diff --git a/go.sum b/go.sum index 6a163348a..a4ed1a047 100644 --- a/go.sum +++ b/go.sum @@ -254,6 +254,8 @@ github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:C github.com/andybalholm/brotli v1.0.1 h1:KqhlKozYbRtJvsPrrEeXcO+N2l6NYT5A2QAFmSULpEc= github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/apparentlymart/go-cidr v1.1.0 h1:2mAhrMoF+nhXqxTzSZMUzDHkLjmIHC+Zzn4tdgBZjnU= +github.com/apparentlymart/go-cidr v1.1.0/go.mod h1:EBcsNrHc3zQeuaeCeCtQruQm+n9/YjEn/vI25Lg7Gwc= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= diff --git a/pkg/analyze/host_analyzer.go b/pkg/analyze/host_analyzer.go index 0f2f05c00..ce8d8d6c2 100644 --- a/pkg/analyze/host_analyzer.go +++ b/pkg/analyze/host_analyzer.go @@ -38,6 +38,8 @@ func GetHostAnalyzer(analyzer *troubleshootv1beta2.HostAnalyze) (HostAnalyzer, b return &AnalyzeHostTCPConnect{analyzer.TCPConnect}, true case analyzer.IPV4Interfaces != nil: return &AnalyzeHostIPV4Interfaces{analyzer.IPV4Interfaces}, true + case analyzer.SubnetAvailable != nil: + return &AnalyzeHostSubnetAvailable{analyzer.SubnetAvailable}, true case analyzer.FilesystemPerformance != nil: return &AnalyzeHostFilesystemPerformance{analyzer.FilesystemPerformance}, true case analyzer.Certificate != nil: diff --git a/pkg/analyze/host_subnetavailable.go b/pkg/analyze/host_subnetavailable.go new file mode 100644 index 000000000..e8b680168 --- /dev/null +++ b/pkg/analyze/host_subnetavailable.go @@ -0,0 +1,82 @@ +package analyzer + +import ( + "encoding/json" + "path/filepath" + + "github.com/pkg/errors" + troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" + "github.com/replicatedhq/troubleshoot/pkg/collect" +) + +type AnalyzeHostSubnetAvailable struct { + hostAnalyzer *troubleshootv1beta2.SubnetAvailableAnalyze +} + +func (a *AnalyzeHostSubnetAvailable) Title() string { + return hostAnalyzerTitleOrDefault(a.hostAnalyzer.AnalyzeMeta, "Subnet Available") +} + +func (a *AnalyzeHostSubnetAvailable) IsExcluded() (bool, error) { + return isExcluded(a.hostAnalyzer.Exclude) +} + +func (a *AnalyzeHostSubnetAvailable) Analyze(getCollectedFileContents func(string) ([]byte, error)) ([]*AnalyzeResult, error) { + hostAnalyzer := a.hostAnalyzer + + name := filepath.Join("host-collectors/subnetAvailable", "result.json") + if hostAnalyzer.CollectorName != "" { + name = filepath.Join("host-collectors/subnetAvailable", hostAnalyzer.CollectorName+".json") + } + contents, err := getCollectedFileContents(name) + if err != nil { + return nil, errors.Wrap(err, "failed to get collected file") + } + + isSubnetAvailable := &collect.SubnetAvailableResult{} + if err := json.Unmarshal(contents, isSubnetAvailable); err != nil { + return nil, errors.Wrap(err, "failed to unmarshal subnetAvailable result") + } + + result := &AnalyzeResult{ + Title: a.Title(), + } + + for _, outcome := range hostAnalyzer.Outcomes { + if outcome.Fail != nil { + if outcome.Fail.When == "" { + result.IsFail = true + result.Message = outcome.Fail.Message + result.URI = outcome.Fail.URI + + return []*AnalyzeResult{result}, nil + } + + if string(isSubnetAvailable.Status) == outcome.Fail.When { + result.IsFail = true + result.Message = outcome.Fail.Message + result.URI = outcome.Fail.URI + + return []*AnalyzeResult{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 []*AnalyzeResult{result}, nil + } + + if string(isSubnetAvailable.Status) == outcome.Pass.When { + result.IsPass = true + result.Message = outcome.Pass.Message + result.URI = outcome.Pass.URI + + return []*AnalyzeResult{result}, nil + } + } + } + + return []*AnalyzeResult{result}, nil +} diff --git a/pkg/apis/troubleshoot/v1beta2/hostanalyzer_shared.go b/pkg/apis/troubleshoot/v1beta2/hostanalyzer_shared.go index a97ce918b..3fa8c757b 100644 --- a/pkg/apis/troubleshoot/v1beta2/hostanalyzer_shared.go +++ b/pkg/apis/troubleshoot/v1beta2/hostanalyzer_shared.go @@ -86,6 +86,12 @@ type IPV4InterfacesAnalyze struct { Outcomes []*Outcome `json:"outcomes" yaml:"outcomes"` } +type SubnetAvailableAnalyze struct { + AnalyzeMeta `json:",inline" yaml:",inline"` + CollectorName string `json:"collectorName,omitempty" yaml:"collectorName,omitempty"` + Outcomes []*Outcome `json:"outcomes" yaml:"outcomes"` +} + type FilesystemPerformanceAnalyze struct { AnalyzeMeta `json:",inline" yaml:",inline"` CollectorName string `json:"collectorName,omitempty" yaml:"collectorName,omitempty"` @@ -137,6 +143,8 @@ type HostAnalyze struct { IPV4Interfaces *IPV4InterfacesAnalyze `json:"ipv4Interfaces,omitempty" yaml:"ipv4Interfaces,omitempty"` + SubnetAvailable *SubnetAvailableAnalyze `json:"subnetAvailable,omitempty" yaml:"subnetAvailable,omitempty"` + FilesystemPerformance *FilesystemPerformanceAnalyze `json:"filesystemPerformance,omitempty" yaml:"filesystemPerformance,omitempty"` Certificate *CertificateAnalyze `json:"certificate,omitempty" yaml:"certificate,omitempty"` diff --git a/pkg/apis/troubleshoot/v1beta2/hostcollector_shared.go b/pkg/apis/troubleshoot/v1beta2/hostcollector_shared.go index 0086ca0d6..99b989e1a 100644 --- a/pkg/apis/troubleshoot/v1beta2/hostcollector_shared.go +++ b/pkg/apis/troubleshoot/v1beta2/hostcollector_shared.go @@ -53,6 +53,12 @@ type IPV4Interfaces struct { HostCollectorMeta `json:",inline" yaml:",inline"` } +type SubnetAvailable struct { + HostCollectorMeta `json:",inline" yaml:",inline"` + CIDRRangeAlloc string `json:"CIDRRangeAlloc" yaml:"CIDRRangeAlloc"` + DesiredCIDR int `json:"desiredCIDR" yaml:"desiredCIDR"` +} + type DiskUsage struct { HostCollectorMeta `json:",inline" yaml:",inline"` Path string `json:"path"` @@ -177,6 +183,7 @@ type HostCollect struct { UDPPortStatus *UDPPortStatus `json:"udpPortStatus,omitempty" yaml:"udpPortStatus,omitempty"` Kubernetes *Kubernetes `json:"kubernetes,omitempty" yaml:"kubernetes,omitempty"` IPV4Interfaces *IPV4Interfaces `json:"ipv4Interfaces,omitempty" yaml:"ipv4Interfaces,omitempty"` + SubnetAvailable *SubnetAvailable `json:"subnetAvailable,omitempty" yaml:"subnetAvailable,omitempty"` DiskUsage *DiskUsage `json:"diskUsage,omitempty" yaml:"diskUsage,omitempty"` HTTP *HostHTTP `json:"http,omitempty" yaml:"http,omitempty"` Time *HostTime `json:"time,omitempty" yaml:"time,omitempty"` diff --git a/pkg/apis/troubleshoot/v1beta2/remote_collector_shared.go b/pkg/apis/troubleshoot/v1beta2/remote_collector_shared.go index 6fd8f4cb2..f2fe62905 100644 --- a/pkg/apis/troubleshoot/v1beta2/remote_collector_shared.go +++ b/pkg/apis/troubleshoot/v1beta2/remote_collector_shared.go @@ -56,6 +56,12 @@ type RemoteIPV4Interfaces struct { RemoteCollectorMeta `json:",inline" yaml:",inline"` } +type RemoteSubnetAvailable struct { + RemoteCollectorMeta `json:",inline" yaml:",inline"` + CIDRRangeAlloc string `json:"CIDRRangeAlloc" yaml:"CIDRRangeAlloc"` + DesiredCIDR int `json:"desiredCIDR" yaml:"desiredCIDR"` +} + type RemoteDiskUsage struct { RemoteCollectorMeta `json:",inline" yaml:",inline"` Path string `json:"path"` @@ -149,6 +155,7 @@ type RemoteCollect struct { TCPPortStatus *RemoteTCPPortStatus `json:"tcpPortStatus,omitempty" yaml:"tcpPortStatus,omitempty"` UDPPortStatus *RemoteUDPPortStatus `json:"udpPortStatus,omitempty" yaml:"udpPortStatus,omitempty"` IPV4Interfaces *RemoteIPV4Interfaces `json:"ipv4Interfaces,omitempty" yaml:"ipv4Interfaces,omitempty"` + SubnetAvailable *RemoteSubnetAvailable `json:"subnetAvailable,omitempty" yaml:"subnetAvailable,omitempty"` DiskUsage *RemoteDiskUsage `json:"diskUsage,omitempty" yaml:"diskUsage,omitempty"` HTTP *RemoteHTTP `json:"http,omitempty" yaml:"http,omitempty"` Time *RemoteTime `json:"time,omitempty" yaml:"time,omitempty"` diff --git a/pkg/apis/troubleshoot/v1beta2/zz_generated.deepcopy.go b/pkg/apis/troubleshoot/v1beta2/zz_generated.deepcopy.go index b60403379..abf8fbe33 100644 --- a/pkg/apis/troubleshoot/v1beta2/zz_generated.deepcopy.go +++ b/pkg/apis/troubleshoot/v1beta2/zz_generated.deepcopy.go @@ -1559,6 +1559,11 @@ func (in *HostAnalyze) DeepCopyInto(out *HostAnalyze) { *out = new(IPV4InterfacesAnalyze) (*in).DeepCopyInto(*out) } + if in.SubnetAvailable != nil { + in, out := &in.SubnetAvailable, &out.SubnetAvailable + *out = new(SubnetAvailableAnalyze) + (*in).DeepCopyInto(*out) + } if in.FilesystemPerformance != nil { in, out := &in.FilesystemPerformance, &out.FilesystemPerformance *out = new(FilesystemPerformanceAnalyze) @@ -1650,6 +1655,11 @@ func (in *HostCollect) DeepCopyInto(out *HostCollect) { *out = new(IPV4Interfaces) (*in).DeepCopyInto(*out) } + if in.SubnetAvailable != nil { + in, out := &in.SubnetAvailable, &out.SubnetAvailable + *out = new(SubnetAvailable) + (*in).DeepCopyInto(*out) + } if in.DiskUsage != nil { in, out := &in.DiskUsage, &out.DiskUsage *out = new(DiskUsage) @@ -3161,6 +3171,11 @@ func (in *RemoteCollect) DeepCopyInto(out *RemoteCollect) { *out = new(RemoteIPV4Interfaces) (*in).DeepCopyInto(*out) } + if in.SubnetAvailable != nil { + in, out := &in.SubnetAvailable, &out.SubnetAvailable + *out = new(RemoteSubnetAvailable) + (*in).DeepCopyInto(*out) + } if in.DiskUsage != nil { in, out := &in.DiskUsage, &out.DiskUsage *out = new(RemoteDiskUsage) @@ -3505,6 +3520,22 @@ func (in *RemoteServices) DeepCopy() *RemoteServices { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RemoteSubnetAvailable) DeepCopyInto(out *RemoteSubnetAvailable) { + *out = *in + in.RemoteCollectorMeta.DeepCopyInto(&out.RemoteCollectorMeta) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RemoteSubnetAvailable. +func (in *RemoteSubnetAvailable) DeepCopy() *RemoteSubnetAvailable { + if in == nil { + return nil + } + out := new(RemoteSubnetAvailable) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RemoteSystemPackages) DeepCopyInto(out *RemoteSystemPackages) { *out = *in @@ -3831,6 +3862,49 @@ func (in *StorageClass) DeepCopy() *StorageClass { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SubnetAvailable) DeepCopyInto(out *SubnetAvailable) { + *out = *in + in.HostCollectorMeta.DeepCopyInto(&out.HostCollectorMeta) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubnetAvailable. +func (in *SubnetAvailable) DeepCopy() *SubnetAvailable { + if in == nil { + return nil + } + out := new(SubnetAvailable) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SubnetAvailableAnalyze) DeepCopyInto(out *SubnetAvailableAnalyze) { + *out = *in + in.AnalyzeMeta.DeepCopyInto(&out.AnalyzeMeta) + if in.Outcomes != nil { + in, out := &in.Outcomes, &out.Outcomes + *out = make([]*Outcome, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(Outcome) + (*in).DeepCopyInto(*out) + } + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubnetAvailableAnalyze. +func (in *SubnetAvailableAnalyze) DeepCopy() *SubnetAvailableAnalyze { + if in == nil { + return nil + } + out := new(SubnetAvailableAnalyze) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SupportBundle) DeepCopyInto(out *SupportBundle) { *out = *in diff --git a/pkg/collect/host_collector.go b/pkg/collect/host_collector.go index 9e538922b..ff9e4448f 100644 --- a/pkg/collect/host_collector.go +++ b/pkg/collect/host_collector.go @@ -45,6 +45,8 @@ func GetHostCollector(collector *troubleshootv1beta2.HostCollect, bundlePath str return &CollectHostTCPConnect{collector.TCPConnect, bundlePath}, true case collector.IPV4Interfaces != nil: return &CollectHostIPV4Interfaces{collector.IPV4Interfaces, bundlePath}, true + case collector.SubnetAvailable != nil: + return &CollectHostSubnetAvailable{collector.SubnetAvailable, bundlePath}, true case collector.FilesystemPerformance != nil: return &CollectHostFilesystemPerformance{collector.FilesystemPerformance, bundlePath}, true case collector.Certificate != nil: diff --git a/pkg/collect/host_subnetavailable.go b/pkg/collect/host_subnetavailable.go new file mode 100644 index 000000000..a1457a185 --- /dev/null +++ b/pkg/collect/host_subnetavailable.go @@ -0,0 +1,278 @@ +package collect + +import ( + "bytes" + "encoding/hex" + "encoding/json" + "fmt" + "net" + "os" + "path/filepath" + "strconv" + "strings" + + "github.com/apparentlymart/go-cidr/cidr" + "github.com/pkg/errors" + troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" + "k8s.io/klog/v2" +) + +type SubnetStatus string + +const ( + SubnetStatusAvailable = "a-subnet-is-available" + SubnetStatusNoneAvailable = "no-subnet-available" +) + +type SubnetAvailableResult struct { + CIDRRangeAlloc string `json:"CIDRRangeAlloc"` + DesiredCIDR int `json:"desiredCIDR"` + // If subnet-available, at least 1 of the DesiredCIDR size is available within CIDRRangeAlloc + Status SubnetStatus `json:"status"` +} + +type CollectHostSubnetAvailable struct { + hostCollector *troubleshootv1beta2.SubnetAvailable + BundlePath string +} + +func (c *CollectHostSubnetAvailable) Title() string { + return hostCollectorTitleOrDefault(c.hostCollector.HostCollectorMeta, "Subnet Available") +} + +func (c *CollectHostSubnetAvailable) IsExcluded() (bool, error) { + return isExcluded(c.hostCollector.Exclude) +} + +func (c *CollectHostSubnetAvailable) Collect(progressChan chan<- interface{}) (map[string][]byte, error) { + procNetRoute, err := os.ReadFile("/proc/net/route") + if err != nil { + return nil, errors.Wrap(err, "failed to read contents of /proc/net/route") + } + + routes, err := parseProcNetRoute(string(procNetRoute)) + if err != nil { + return nil, errors.Wrap(err, "failed to parse /proc/net/route") + } + klog.V(3).Infof("Routes: %+v\n", routes) + + // IPv4 only right now... + if c.hostCollector.DesiredCIDR < 1 || c.hostCollector.DesiredCIDR > 32 { + return nil, errors.Wrap(err, fmt.Sprintf("CIDR range size %d invalid, must be between 1 and 32", c.hostCollector.DesiredCIDR)) + } + + splitCIDRRangeAlloc := strings.Split(c.hostCollector.CIDRRangeAlloc, "/") + if len(splitCIDRRangeAlloc) != 2 { + return nil, errors.Wrap(err, fmt.Sprintf("CIDRRangeAlloc value %s invalid, expected format x.x.x.x/##", c.hostCollector.CIDRRangeAlloc)) + } + maskInt, err := strconv.Atoi(splitCIDRRangeAlloc[1]) + if err != nil { + return nil, errors.Wrap(err, fmt.Sprintf("CIDRRangeAlloc mask %s invalid, expected integer", splitCIDRRangeAlloc[1])) + } + if maskInt < 0 || maskInt > 32 { + return nil, errors.Wrap(err, fmt.Sprintf("CIDRRangeAlloc mask %d invalid, must be between 0 and 32", maskInt)) + } + cidrRangeAllocIPNet := net.IPNet{ + IP: net.ParseIP(splitCIDRRangeAlloc[0]), + Mask: net.CIDRMask(maskInt, 32), + } + + result := SubnetAvailableResult{} + result.CIDRRangeAlloc = c.hostCollector.CIDRRangeAlloc + result.DesiredCIDR = c.hostCollector.DesiredCIDR + available, err := isASubnetAvailableInCIDR(c.hostCollector.DesiredCIDR, &cidrRangeAllocIPNet, &routes) + if err != nil { + return nil, errors.Wrap(err, "failed to determine if desired CIDR is available within subnet") + } + if available == true { + result.Status = SubnetStatusAvailable + } else { + result.Status = SubnetStatusNoneAvailable + } + + b, err := json.Marshal(result) + if err != nil { + return nil, errors.Wrap(err, "failed to marshal result") + } + + collectorName := c.hostCollector.CollectorName + if collectorName == "" { + collectorName = "result" + } + name := filepath.Join("host-collectors/subnetAvailable", collectorName+".json") + + output := NewResult() + output.SaveResult(c.BundlePath, name, bytes.NewBuffer(b)) + + return map[string][]byte{ + name: b, + }, nil +} + +type systemRoutes []systemRoute + +type systemRoute struct { + Iface string + DestNet net.IPNet + Gateway net.IP + Metric uint32 +} + +// Parses the output of /proc/net/route into something useful +// This only deals with IPv4 - another file /proc/net/ipv6_route deals with IPv6 (not implemented here) +func parseProcNetRoute(input string) (systemRoutes, error) { + routes := systemRoutes{} + for _, line := range strings.Split(input, "\n") { + if len(line) < 4 { + // Likely a blank line? + continue + } + if line[0:5] == "Iface" { + continue + } + + splitLine := strings.Split(strings.TrimSpace(line), "\t") + if len(splitLine) != 11 { + return []systemRoute{}, errors.Errorf("invalid /proc/net/route line '%s', expected 11 columns got %d", line, len(splitLine)) + } + + dest, err := hex.DecodeString(strings.TrimSpace(splitLine[1])) + if err != nil { + return []systemRoute{}, errors.Wrapf(err, "cannot parse dest column (index 1) for /proc/net/route line '%s'", line) + } + destStr := fmt.Sprintf("%d.%d.%d.%d", dest[3], dest[2], dest[1], dest[0]) + + gw, err := hex.DecodeString(strings.TrimSpace(splitLine[2])) + if err != nil { + return []systemRoute{}, errors.Wrapf(err, "cannot parse gateway column (index 2) for /proc/net/route line '%s'", line) + } + gwStr := fmt.Sprintf("%d.%d.%d.%d", gw[3], gw[2], gw[1], gw[0]) + + mask, err := hex.DecodeString(strings.TrimSpace(splitLine[7])) + if err != nil { + return []systemRoute{}, errors.Wrapf(err, "cannot parse mask column (index 7) for /proc/net/route line '%s'", line) + } + maskStr := fmt.Sprintf("%d.%d.%d.%d", mask[3], mask[2], mask[1], mask[0]) + maskBytes := []byte{} + for _, v := range strings.Split(maskStr, ".") { + maskByte, err := strconv.Atoi(v) + if err != nil { + return []systemRoute{}, errors.Wrapf(err, "cannot convert mask octet '%s' to byte", v) + } + maskBytes = append(maskBytes, byte(maskByte)) + } + + metric, err := strconv.Atoi(strings.TrimSpace(splitLine[6])) + if err != nil { + return []systemRoute{}, errors.Wrapf(err, "cannot parse metric column (index 6) for /proc/net/route line '%s'", line) + } + + routes = append(routes, systemRoute{ + Iface: strings.TrimSpace(splitLine[0]), + DestNet: net.IPNet{ + IP: net.ParseIP(destStr), + Mask: net.IPv4Mask(maskBytes[0], maskBytes[1], maskBytes[2], maskBytes[3]), + }, + Gateway: net.ParseIP(gwStr), + Metric: uint32(metric), + }) + } + + return routes, nil +} + +// Credit: https://github.com/replicatedhq/kURL/blob/main/kurl_util/cmd/subnet/main.go findAvailableSubnet +// TODOLATER: consolidate some of this logic into a unified library? will need a bit of refactoring if so +// +// isASubnetAvailableInCIDR will check if a subnet of cidrRange size is available within subnetRange (IPv4 only), checking against system routes for conflicts +func isASubnetAvailableInCIDR(cidrRange int, subnetRange *net.IPNet, routes *systemRoutes) (bool, error) { + // Sanity check that the CIDR range size is IPv4 valid (/0 to /32) + if cidrRange < 1 || cidrRange > 32 { + return false, errors.New(fmt.Sprintf("CIDR range size %d invalid, must be between 1 and 32", cidrRange)) + } + + // Check that cidrRange is equal to or smaller than the subnet size of subnetRange + // Always exit false if not... + subnetRangeSize, subnetRangeSizeBits := subnetRange.Mask.Size() + if subnetRangeSizeBits != 32 { + return false, errors.New(fmt.Sprintf("subnetRange size is not IPv4 compatible? expected 32 got %d", subnetRangeSizeBits)) + } + // NOTE: reversed operator as we're talking about CIDR blocks (smaller integer = more IPs) + if subnetRangeSize > cidrRange { + return false, errors.New(fmt.Sprintf("subnetRange size (%d) must be larger than or equal to cidrRange size (%d), can't check if a range larger than itself is available", subnetRangeSize, cidrRange)) + } + + // Find the start IP of subnetRange, this will become the first subnet to be tested (with cidrRange as the size) + startIP, _ := cidr.AddressRange(subnetRange) + + _, subnet, err := net.ParseCIDR(fmt.Sprintf("%s/%d", startIP, cidrRange)) + if err != nil { + return false, errors.Wrap(err, "parse cidr") + } + + for { + // This is the extents of the subnet to be tested + firstIP, lastIP := cidr.AddressRange(subnet) + klog.V(2).Infof("Checking subnet: %s firstIP: %s lastIP: %s\n", subnet.String(), firstIP, lastIP) + + // Make sure the smaller subnet is (still) within the large subnetRange. If subnetRange has been exhausted one of these will be false + if !subnetRange.Contains(firstIP) || !subnetRange.Contains(lastIP) { + return false, nil + } + + // Check if any system routes overlap with the smaller subnet being tested + route := findFirstOverlappingRoute(subnet, routes) + if route == nil { + // No system routes match, this (smaller) subnet is available + klog.V(1).Infof("Subnet %s is available", subnet.String()) + return true, nil + } + + // Try the next subnet in the range + subnet, _ = cidr.NextSubnet(subnet, cidrRange) + } +} + +// findFirstOverlappingRoute will return the first overlapping route with the subnet specified +func findFirstOverlappingRoute(subnet *net.IPNet, routes *systemRoutes) *systemRoute { + // NOTE: IPv4 specific + defaultRoute := net.IPNet{ + IP: net.IPv4(0, 0, 0, 0), + Mask: net.CIDRMask(0, 32), + } + + for _, route := range *routes { + // Exclude default routes (0.0.0.0/0) + if route.DestNet.IP.Equal(defaultRoute.IP) && route.DestNet.Mask.String() == defaultRoute.Mask.String() { + continue + } + + klog.V(2).Infof("Checking if route %s overlaps with subnet %s - ", &route.DestNet, subnet) + // TODOLATER: can we use cidr.VerifyNoOverlap to replace this? tests fail right now trying to do so... + //if cidr.VerifyNoOverlap([]*net.IPNet{subnet}, &route.DestNet) != nil { + if netOverlaps(&route.DestNet, subnet) { + klog.V(2).Infof("Overlaps\n") + return &route + } else { + klog.V(2).Infof("No overlap\n") + } + } + klog.V(2).Infof("Subnet %s has no overlap with any system routes\n", subnet) + return nil +} + +func netOverlaps(n1, n2 *net.IPNet) bool { + n1FirstIP, n1LastIP := cidr.AddressRange(n1) + n2FirstIP, n2LastIP := cidr.AddressRange(n2) + + // Check if the first net contains either the first or last IP of the second net + if n1.Contains(n2FirstIP) || n1.Contains(n2LastIP) { + return true + } + // Now do the reverse: check if the second net contains either the first or last IP of the first net + if n2.Contains(n1FirstIP) || n2.Contains(n1LastIP) { + return true + } + + return false +} diff --git a/pkg/collect/host_subnetavailable_test.go b/pkg/collect/host_subnetavailable_test.go new file mode 100644 index 000000000..27271f677 --- /dev/null +++ b/pkg/collect/host_subnetavailable_test.go @@ -0,0 +1,203 @@ +package collect + +import ( + "net" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestParseProcNetRoute(t *testing.T) { + input := `Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT +eth1 00000000 016BA8C0 0003 0 0 200 00000000 0 0 0 +eth0 00000000 0205A8C0 0003 0 0 202 00000000 0 0 0 +docker0 000011AC 00000000 0001 0 0 0 0000FFFF 0 0 0 +eth0 0005A8C0 00000000 0001 0 0 0 00FFFFFF 0 0 0 +eth1 006BA8C0 00000000 0001 0 0 0 00FFFFFF 0 0 0` + + /* + Destination Gateway Genmask Flags Metric Ref Use Iface + 0.0.0.0 192.168.107.1 0.0.0.0 UG 200 0 0 eth1 + 0.0.0.0 192.168.5.2 0.0.0.0 UG 202 0 0 eth0 + 172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0 + 192.168.5.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 + 192.168.107.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1 + */ + + expected := systemRoutes{ + systemRoute{ + Iface: "eth1", + DestNet: net.IPNet{ + IP: net.IPv4(0, 0, 0, 0), + Mask: net.CIDRMask(0, 32), + }, + Gateway: net.IPv4(192, 168, 107, 1), + Metric: uint32(200), + }, + systemRoute{ + Iface: "eth0", + DestNet: net.IPNet{ + IP: net.IPv4(0, 0, 0, 0), + Mask: net.CIDRMask(0, 32), + }, + Gateway: net.IPv4(192, 168, 5, 2), + Metric: uint32(202), + }, + systemRoute{ + Iface: "docker0", + DestNet: net.IPNet{ + IP: net.IPv4(172, 17, 0, 0), + Mask: net.CIDRMask(16, 32), + }, + Gateway: net.IPv4(0, 0, 0, 0), + Metric: uint32(0), + }, + systemRoute{ + Iface: "eth0", + DestNet: net.IPNet{ + IP: net.IPv4(192, 168, 5, 0), + Mask: net.CIDRMask(24, 32), + }, + Gateway: net.IPv4(0, 0, 0, 0), + Metric: uint32(0), + }, + systemRoute{ + Iface: "eth1", + DestNet: net.IPNet{ + IP: net.IPv4(192, 168, 107, 0), + Mask: net.CIDRMask(24, 32), + }, + Gateway: net.IPv4(0, 0, 0, 0), + Metric: uint32(0), + }, + } + + result, err := parseProcNetRoute(input) + + require.NoError(t, err) + assert.Equal(t, expected, result) +} + +func TestIsASubnetAvailableInCIDR(t *testing.T) { + // Single routing table used for all tests + sysRoutes := systemRoutes{ + systemRoute{ + Iface: "eth1", + DestNet: net.IPNet{ + IP: net.IPv4(0, 0, 0, 0), + Mask: net.CIDRMask(0, 32), + }, + Gateway: net.IPv4(192, 168, 107, 1), + Metric: uint32(200), + }, + systemRoute{ + Iface: "eth0", + DestNet: net.IPNet{ + IP: net.IPv4(0, 0, 0, 0), + Mask: net.CIDRMask(0, 32), + }, + Gateway: net.IPv4(192, 168, 5, 2), + Metric: uint32(202), + }, + systemRoute{ + Iface: "docker0", + DestNet: net.IPNet{ + IP: net.IPv4(172, 17, 0, 0), + Mask: net.CIDRMask(16, 32), + }, + Gateway: net.IPv4(0, 0, 0, 0), + Metric: uint32(0), + }, + systemRoute{ + Iface: "docker1", + DestNet: net.IPNet{ + IP: net.IPv4(172, 16, 0, 0), + Mask: net.CIDRMask(16, 32), + }, + Gateway: net.IPv4(0, 0, 0, 0), + Metric: uint32(0), + }, + systemRoute{ + Iface: "eth0", + DestNet: net.IPNet{ + IP: net.IPv4(192, 168, 5, 0), + Mask: net.CIDRMask(24, 32), + }, + Gateway: net.IPv4(0, 0, 0, 0), + Metric: uint32(0), + }, + systemRoute{ + Iface: "eth1", + DestNet: net.IPNet{ + IP: net.IPv4(192, 168, 107, 0), + Mask: net.CIDRMask(24, 32), + }, + Gateway: net.IPv4(0, 0, 0, 0), + Metric: uint32(0), + }, + } + + tests := []struct { + name string + cidrRange int + subnetRange net.IPNet + expected bool + }{ + { + name: "unavailable 1", + cidrRange: 24, + subnetRange: net.IPNet{ + IP: net.IPv4(172, 17, 0, 0), + Mask: net.CIDRMask(20, 32), + }, + expected: false, + }, + { + name: "unavailable 2", + cidrRange: 27, + subnetRange: net.IPNet{ + IP: net.IPv4(192, 168, 5, 0), + Mask: net.CIDRMask(24, 32), + }, + expected: false, + }, + { + name: "available 1", + cidrRange: 23, + subnetRange: net.IPNet{ + IP: net.IPv4(172, 20, 0, 0), + Mask: net.CIDRMask(16, 32), + }, + expected: true, + }, + { + name: "available 2", + cidrRange: 24, + subnetRange: net.IPNet{ + IP: net.IPv4(10, 0, 0, 0), + Mask: net.CIDRMask(8, 32), + }, + expected: true, + }, + { + name: "available 3", + cidrRange: 24, + subnetRange: net.IPNet{ + IP: net.IPv4(172, 16, 0, 0), + Mask: net.CIDRMask(12, 32), + }, + expected: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + req := require.New(t) + actual, err := isASubnetAvailableInCIDR(tt.cidrRange, &tt.subnetRange, &sysRoutes) // debug bool is useful for fixing bugs here, but off by default for noise + req.NoError(err) + + assert.Equal(t, tt.expected, actual) + }) + } +} diff --git a/pkg/collect/remote_collector.go b/pkg/collect/remote_collector.go index 6db6ab962..57570c15c 100644 --- a/pkg/collect/remote_collector.go +++ b/pkg/collect/remote_collector.go @@ -268,6 +268,13 @@ func (c *RemoteCollector) toHostCollector() (*troubleshootv1beta2.HostCollect, e Exclude: c.Collect.IPV4Interfaces.Exclude, }, } + case c.Collect.SubnetAvailable != nil: + hostCollect.SubnetAvailable = &troubleshootv1beta2.SubnetAvailable{ + HostCollectorMeta: troubleshootv1beta2.HostCollectorMeta{ + CollectorName: c.Collect.IPV4Interfaces.CollectorName, + Exclude: c.Collect.IPV4Interfaces.Exclude, + }, + } case c.Collect.FilesystemPerformance != nil: hostCollect.FilesystemPerformance = &troubleshootv1beta2.FilesystemPerformance{ HostCollectorMeta: troubleshootv1beta2.HostCollectorMeta{ diff --git a/schemas/analyzer-troubleshoot-v1beta2.json b/schemas/analyzer-troubleshoot-v1beta2.json index de20cdcf2..9cfc5368e 100644 --- a/schemas/analyzer-troubleshoot-v1beta2.json +++ b/schemas/analyzer-troubleshoot-v1beta2.json @@ -3213,6 +3213,82 @@ } } }, + "subnetAvailable": { + "type": "object", + "required": [ + "outcomes" + ], + "properties": { + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "checkName": { + "type": "string" + }, + "collectorName": { + "type": "string" + }, + "exclude": { + "oneOf": [{"type": "string"},{"type": "boolean"}] + }, + "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"}] + } + } + }, "systemPackages": { "type": "object", "required": [ diff --git a/schemas/preflight-troubleshoot-v1beta2.json b/schemas/preflight-troubleshoot-v1beta2.json index 68aeab4c0..6f4eb0fb3 100644 --- a/schemas/preflight-troubleshoot-v1beta2.json +++ b/schemas/preflight-troubleshoot-v1beta2.json @@ -9428,6 +9428,27 @@ } } }, + "subnetAvailable": { + "type": "object", + "required": [ + "CIDRRangeAlloc", + "desiredCIDR" + ], + "properties": { + "CIDRRangeAlloc": { + "type": "string" + }, + "collectorName": { + "type": "string" + }, + "desiredCIDR": { + "type": "integer" + }, + "exclude": { + "oneOf": [{"type": "string"},{"type": "boolean"}] + } + } + }, "systemPackages": { "type": "object", "properties": { diff --git a/schemas/supportbundle-troubleshoot-v1beta2.json b/schemas/supportbundle-troubleshoot-v1beta2.json index 35bccafcc..42bae52c0 100644 --- a/schemas/supportbundle-troubleshoot-v1beta2.json +++ b/schemas/supportbundle-troubleshoot-v1beta2.json @@ -10117,6 +10117,82 @@ } } }, + "subnetAvailable": { + "type": "object", + "required": [ + "outcomes" + ], + "properties": { + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "checkName": { + "type": "string" + }, + "collectorName": { + "type": "string" + }, + "exclude": { + "oneOf": [{"type": "string"},{"type": "boolean"}] + }, + "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"}] + } + } + }, "systemPackages": { "type": "object", "required": [ @@ -10905,6 +10981,27 @@ } } }, + "subnetAvailable": { + "type": "object", + "required": [ + "CIDRRangeAlloc", + "desiredCIDR" + ], + "properties": { + "CIDRRangeAlloc": { + "type": "string" + }, + "collectorName": { + "type": "string" + }, + "desiredCIDR": { + "type": "integer" + }, + "exclude": { + "oneOf": [{"type": "string"},{"type": "boolean"}] + } + } + }, "systemPackages": { "type": "object", "properties": { From 156f502713332aa2f115643ae8781de2feb50adb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Mar 2023 14:59:55 +0000 Subject: [PATCH 45/55] 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> --- go.mod | 4 ++-- go.sum | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 90d62fbd9..d38c908ed 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.19 require ( github.com/ahmetalpbalkan/go-cursor v0.0.0-20131010032410-8136607ea412 + github.com/apparentlymart/go-cidr v1.1.0 github.com/blang/semver/v4 v4.0.0 github.com/containers/image/v5 v5.24.2 github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2 @@ -40,7 +41,7 @@ require ( gopkg.in/yaml.v2 v2.4.0 k8s.io/api v0.26.1 k8s.io/apiextensions-apiserver v0.26.1 - k8s.io/apimachinery v0.26.1 + k8s.io/apimachinery v0.26.2 k8s.io/apiserver v0.26.1 k8s.io/cli-runtime v0.26.1 k8s.io/client-go v0.26.1 @@ -51,7 +52,6 @@ require ( require ( cloud.google.com/go/compute/metadata v0.2.3 // indirect - github.com/apparentlymart/go-cidr v1.1.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/docker/distribution v2.8.1+incompatible // indirect github.com/emicklei/go-restful/v3 v3.9.0 // indirect diff --git a/go.sum b/go.sum index a4ed1a047..653d86deb 100644 --- a/go.sum +++ b/go.sum @@ -1957,8 +1957,8 @@ k8s.io/apiextensions-apiserver v0.26.1/go.mod h1:AptjOSXDGuE0JICx/Em15PaoO7buLwT k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc= -k8s.io/apimachinery v0.26.1 h1:8EZ/eGJL+hY/MYCNwhmDzVqq2lPl3N3Bo8rvweJwXUQ= -k8s.io/apimachinery v0.26.1/go.mod h1:tnPmbONNJ7ByJNz9+n9kMjNP8ON+1qoAIIC70lztu74= +k8s.io/apimachinery v0.26.2 h1:da1u3D5wfR5u2RpLhE/ZtZS2P7QvDgLZTi9wrNZl/tQ= +k8s.io/apimachinery v0.26.2/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5I= k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU= k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM= k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q= From 3c001b1a2b9579dbef9f1c0d729daf61fc0b9a9c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Mar 2023 15:02:34 +0000 Subject: [PATCH 46/55] 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> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index d38c908ed..1e4e4b156 100644 --- a/go.mod +++ b/go.mod @@ -47,7 +47,7 @@ require ( k8s.io/client-go v0.26.1 k8s.io/klog/v2 v2.90.0 oras.land/oras-go v1.2.2 - sigs.k8s.io/controller-runtime v0.14.4 + sigs.k8s.io/controller-runtime v0.14.5 ) require ( diff --git a/go.sum b/go.sum index 653d86deb..893be6f96 100644 --- a/go.sum +++ b/go.sum @@ -2004,8 +2004,8 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= -sigs.k8s.io/controller-runtime v0.14.4 h1:Kd/Qgx5pd2XUL08eOV2vwIq3L9GhIbJ5Nxengbd4/0M= -sigs.k8s.io/controller-runtime v0.14.4/go.mod h1:WqIdsAY6JBsjfc/CqO0CORmNtoCtE4S6qbPc9s68h+0= +sigs.k8s.io/controller-runtime v0.14.5 h1:6xaWFqzT5KuAQ9ufgUaj1G/+C4Y1GRkhrxl+BJ9i+5s= +sigs.k8s.io/controller-runtime v0.14.5/go.mod h1:WqIdsAY6JBsjfc/CqO0CORmNtoCtE4S6qbPc9s68h+0= sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k= sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/kustomize/api v0.12.1 h1:7YM7gW3kYBwtKvoY216ZzY+8hM+lV53LUayghNRJ0vM= From 244c05986b66a6a53bb9eecd5576f3d8b367f231 Mon Sep 17 00:00:00 2001 From: ada mancini Date: Tue, 14 Mar 2023 10:13:42 -0500 Subject: [PATCH 47/55] dont run tests on draft PRs (#966) Co-authored-by: Xav Paice --- .github/workflows/build-test-deploy.yaml | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-test-deploy.yaml b/.github/workflows/build-test-deploy.yaml index af8d5e48a..cf69b20b6 100644 --- a/.github/workflows/build-test-deploy.yaml +++ b/.github/workflows/build-test-deploy.yaml @@ -1,5 +1,10 @@ on: pull_request: + types: + - opened + - reopened + - synchronize + - ready_for_review branches: - main push: @@ -13,6 +18,13 @@ concurrency: 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: @@ -56,7 +68,7 @@ jobs: steps: - uses: actions/setup-go@v3 with: - go-version: '1.19' + go-version: "1.19" - name: setup env run: | echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV @@ -70,7 +82,7 @@ jobs: steps: - uses: actions/setup-go@v3 with: - go-version: '1.19' + go-version: "1.19" - name: setup env run: | echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV @@ -146,7 +158,7 @@ jobs: steps: - uses: actions/setup-go@v3 with: - go-version: '1.19' + go-version: "1.19" - name: setup env run: | echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV @@ -200,7 +212,7 @@ jobs: steps: - uses: actions/setup-go@v3 with: - go-version: '1.19' + go-version: "1.19" - name: setup env run: | echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV @@ -288,7 +300,6 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Update new preflight version in krew-index uses: rajatjindal/krew-release-bot@v0.0.43 with: From 5d06e4641a7bf9de6ad868b4aec1bca46676cf15 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Mar 2023 15:44:16 +0000 Subject: [PATCH 48/55] 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> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 1e4e4b156..91deaa9a6 100644 --- a/go.mod +++ b/go.mod @@ -45,7 +45,7 @@ require ( k8s.io/apiserver v0.26.1 k8s.io/cli-runtime v0.26.1 k8s.io/client-go v0.26.1 - k8s.io/klog/v2 v2.90.0 + k8s.io/klog/v2 v2.90.1 oras.land/oras-go v1.2.2 sigs.k8s.io/controller-runtime v0.14.5 ) diff --git a/go.sum b/go.sum index 893be6f96..2abe63a0c 100644 --- a/go.sum +++ b/go.sum @@ -1985,8 +1985,8 @@ k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAE k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= -k8s.io/klog/v2 v2.90.0 h1:VkTxIV/FjRXn1fgNNcKGM8cfmL1Z33ZjXRTVxKCoF5M= -k8s.io/klog/v2 v2.90.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw= +k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o= k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 h1:+70TFaan3hfJzs+7VK2o+OGxg8HsuBr/5f6tVAjDu6E= From 410aa81e8835a76c69974f3d2724a7174835bbb9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Mar 2023 17:04:43 +0000 Subject: [PATCH 49/55] 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> --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 91deaa9a6..ba158fcb0 100644 --- a/go.mod +++ b/go.mod @@ -39,12 +39,12 @@ require ( go.opentelemetry.io/otel/sdk v1.14.0 golang.org/x/sync v0.1.0 gopkg.in/yaml.v2 v2.4.0 - k8s.io/api v0.26.1 + k8s.io/api v0.26.2 k8s.io/apiextensions-apiserver v0.26.1 k8s.io/apimachinery v0.26.2 k8s.io/apiserver v0.26.1 - k8s.io/cli-runtime v0.26.1 - k8s.io/client-go v0.26.1 + k8s.io/cli-runtime v0.26.2 + k8s.io/client-go v0.26.2 k8s.io/klog/v2 v2.90.1 oras.land/oras-go v1.2.2 sigs.k8s.io/controller-runtime v0.14.5 diff --git a/go.sum b/go.sum index 2abe63a0c..bea6cfa1b 100644 --- a/go.sum +++ b/go.sum @@ -1950,8 +1950,8 @@ honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo= k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ= k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8= -k8s.io/api v0.26.1 h1:f+SWYiPd/GsiWwVRz+NbFyCgvv75Pk9NK6dlkZgpCRQ= -k8s.io/api v0.26.1/go.mod h1:xd/GBNgR0f707+ATNyPmQ1oyKSgndzXij81FzWGsejg= +k8s.io/api v0.26.2 h1:dM3cinp3PGB6asOySalOZxEG4CZ0IAdJsrYZXE/ovGQ= +k8s.io/api v0.26.2/go.mod h1:1kjMQsFE+QHPfskEcVNgL3+Hp88B80uj0QtSOlj8itU= k8s.io/apiextensions-apiserver v0.26.1 h1:cB8h1SRk6e/+i3NOrQgSFij1B2S0Y0wDoNl66bn8RMI= k8s.io/apiextensions-apiserver v0.26.1/go.mod h1:AptjOSXDGuE0JICx/Em15PaoO7buLwTs0dGleIHixSM= k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= @@ -1964,13 +1964,13 @@ k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM= k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q= k8s.io/apiserver v0.26.1 h1:6vmnAqCDO194SVCPU3MU8NcDgSqsUA62tBUSWrFXhsc= k8s.io/apiserver v0.26.1/go.mod h1:wr75z634Cv+sifswE9HlAo5FQ7UoUauIICRlOE+5dCg= -k8s.io/cli-runtime v0.26.1 h1:f9+bRQ1V3elQsx37KmZy5fRAh56mVLbE9A7EMdlqVdI= -k8s.io/cli-runtime v0.26.1/go.mod h1:+e5Ym/ARySKscUhZ8K3hZ+ZBo/wYPIcg+7b5sFYi6Gg= +k8s.io/cli-runtime v0.26.2 h1:6XcIQOYW1RGNwFgRwejvyUyAojhToPmJLGr0JBMC5jw= +k8s.io/cli-runtime v0.26.2/go.mod h1:U7sIXX7n6ZB+MmYQsyJratzPeJwgITqrSlpr1a5wM5I= k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y= k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k= k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0= -k8s.io/client-go v0.26.1 h1:87CXzYJnAMGaa/IDDfRdhTzxk/wzGZ+/HUQpqgVSZXU= -k8s.io/client-go v0.26.1/go.mod h1:IWNSglg+rQ3OcvDkhY6+QLeasV4OYHDjdqeWkDQZwGE= +k8s.io/client-go v0.26.2 h1:s1WkVujHX3kTp4Zn4yGNFK+dlDXy1bAAkIl+cFAiuYI= +k8s.io/client-go v0.26.2/go.mod h1:u5EjOuSyBa09yqqyY7m3abZeovO/7D/WehVVlZ2qcqU= k8s.io/code-generator v0.19.7/go.mod h1:lwEq3YnLYb/7uVXLorOJfxg+cUu2oihFhHZ0n9NIla0= k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk= k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI= From 944022aca82260342424326cf5b68591f2a1a619 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Mar 2023 11:08:40 +0000 Subject: [PATCH 50/55] 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 --- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index ba158fcb0..2f7a69fc9 100644 --- a/go.mod +++ b/go.mod @@ -40,12 +40,12 @@ require ( golang.org/x/sync v0.1.0 gopkg.in/yaml.v2 v2.4.0 k8s.io/api v0.26.2 - k8s.io/apiextensions-apiserver v0.26.1 + k8s.io/apiextensions-apiserver v0.26.2 k8s.io/apimachinery v0.26.2 - k8s.io/apiserver v0.26.1 - k8s.io/cli-runtime v0.26.2 + k8s.io/apiserver v0.26.2 + k8s.io/cli-runtime v0.26.1 k8s.io/client-go v0.26.2 - k8s.io/klog/v2 v2.90.1 + k8s.io/klog/v2 v2.90.0 oras.land/oras-go v1.2.2 sigs.k8s.io/controller-runtime v0.14.5 ) diff --git a/go.sum b/go.sum index bea6cfa1b..47ae89a0f 100644 --- a/go.sum +++ b/go.sum @@ -1952,8 +1952,8 @@ k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ= k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8= k8s.io/api v0.26.2 h1:dM3cinp3PGB6asOySalOZxEG4CZ0IAdJsrYZXE/ovGQ= k8s.io/api v0.26.2/go.mod h1:1kjMQsFE+QHPfskEcVNgL3+Hp88B80uj0QtSOlj8itU= -k8s.io/apiextensions-apiserver v0.26.1 h1:cB8h1SRk6e/+i3NOrQgSFij1B2S0Y0wDoNl66bn8RMI= -k8s.io/apiextensions-apiserver v0.26.1/go.mod h1:AptjOSXDGuE0JICx/Em15PaoO7buLwTs0dGleIHixSM= +k8s.io/apiextensions-apiserver v0.26.2 h1:/yTG2B9jGY2Q70iGskMf41qTLhL9XeNN2KhI0uDgwko= +k8s.io/apiextensions-apiserver v0.26.2/go.mod h1:Y7UPgch8nph8mGCuVk0SK83LnS8Esf3n6fUBgew8SH8= k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc= @@ -1962,10 +1962,10 @@ k8s.io/apimachinery v0.26.2/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5 k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU= k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM= k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q= -k8s.io/apiserver v0.26.1 h1:6vmnAqCDO194SVCPU3MU8NcDgSqsUA62tBUSWrFXhsc= -k8s.io/apiserver v0.26.1/go.mod h1:wr75z634Cv+sifswE9HlAo5FQ7UoUauIICRlOE+5dCg= -k8s.io/cli-runtime v0.26.2 h1:6XcIQOYW1RGNwFgRwejvyUyAojhToPmJLGr0JBMC5jw= -k8s.io/cli-runtime v0.26.2/go.mod h1:U7sIXX7n6ZB+MmYQsyJratzPeJwgITqrSlpr1a5wM5I= +k8s.io/apiserver v0.26.2 h1:Pk8lmX4G14hYqJd1poHGC08G03nIHVqdJMR0SD3IH3o= +k8s.io/apiserver v0.26.2/go.mod h1:GHcozwXgXsPuOJ28EnQ/jXEM9QeG6HT22YxSNmpYNh8= +k8s.io/cli-runtime v0.26.1 h1:f9+bRQ1V3elQsx37KmZy5fRAh56mVLbE9A7EMdlqVdI= +k8s.io/cli-runtime v0.26.1/go.mod h1:+e5Ym/ARySKscUhZ8K3hZ+ZBo/wYPIcg+7b5sFYi6Gg= k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y= k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k= k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0= @@ -1985,8 +1985,8 @@ k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAE k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= -k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw= -k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.90.0 h1:VkTxIV/FjRXn1fgNNcKGM8cfmL1Z33ZjXRTVxKCoF5M= +k8s.io/klog/v2 v2.90.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o= k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 h1:+70TFaan3hfJzs+7VK2o+OGxg8HsuBr/5f6tVAjDu6E= From a7b30600693a9a95eb379c6bd2aa9d620729328e Mon Sep 17 00:00:00 2001 From: Chase Hainey Date: Mon, 20 Mar 2023 12:43:47 -0600 Subject: [PATCH 51/55] Adds MSSQL collector based on Postgres collector --- go.mod | 3 ++- go.sum | 13 +++++++------ pkg/collect/mssql.go | 29 +++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index 2f7a69fc9..e514cff13 100644 --- a/go.mod +++ b/go.mod @@ -59,7 +59,8 @@ require ( github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe // indirect github.com/golang-sql/sqlexp v0.1.0 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.2.1 // indirect + github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe // indirect + github.com/golang-sql/sqlexp v0.1.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect diff --git a/go.sum b/go.sum index 47ae89a0f..391bc44bb 100644 --- a/go.sum +++ b/go.sum @@ -767,15 +767,12 @@ 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= -<<<<<<< HEAD github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.3.0 h1:McDWVJIU/y+u1BRV06dPaLfLCaT7fUTJLp5r04x7iNw= github.com/hashicorp/go-version v1.3.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -======= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= ->>>>>>> 661a948 (chore(deps): bump github.com/hashicorp/go-getter from 1.6.2 to 1.7.0 (#1019)) github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= @@ -797,6 +794,10 @@ github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLf github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= +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/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg= github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= github.com/jackc/pgx/v5 v5.2.0 h1:NdPpngX0Y6z6XDFKqmFQaE+bCtkqzvQIOt1wvBlAqs8= @@ -1279,6 +1280,8 @@ golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm 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.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= +golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= @@ -1540,10 +1543,8 @@ 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= -<<<<<<< HEAD golang.org/x/sys v0.0.0-20220224120231-95c6836cb0e7/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -======= ->>>>>>> 661a948 (chore(deps): bump github.com/hashicorp/go-getter from 1.6.2 to 1.7.0 (#1019)) +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= diff --git a/pkg/collect/mssql.go b/pkg/collect/mssql.go index d19387515..443dd27bc 100644 --- a/pkg/collect/mssql.go +++ b/pkg/collect/mssql.go @@ -15,12 +15,17 @@ import ( "k8s.io/client-go/rest" ) +<<<<<<< HEAD type CollectMssql struct { +======= +type CollectMSSql struct { +>>>>>>> ffcf962 (Adds MSSQL collector based on Postgres collector) Collector *troubleshootv1beta2.Database BundlePath string Namespace string ClientConfig *rest.Config Client kubernetes.Interface +<<<<<<< HEAD Context context.Context RBACErrors } @@ -34,6 +39,21 @@ func (c *CollectMssql) IsExcluded() (bool, error) { } func (c *CollectMssql) Collect(progressChan chan<- interface{}) (CollectorResult, error) { +======= + ctx context.Context + RBACErrors +} + +func (c *CollectMSSql) Title() string { + return collectorTitleOrDefault(c.Collector.CollectorMeta, "MSSSQLServer") +} + +func (c *CollectMSSql) IsExcluded() (bool, error) { + return isExcluded(c.Collector.Exclude) +} + +func (c *CollectMSSql) Collect(progressChan chan<- interface{}) (CollectorResult, error) { +>>>>>>> ffcf962 (Adds MSSQL collector based on Postgres collector) databaseConnection := DatabaseConnection{} db, err := sql.Open("mssql", c.Collector.URI) @@ -48,7 +68,11 @@ func (c *CollectMssql) Collect(progressChan chan<- interface{}) (CollectorResult } else { databaseConnection.IsConnected = true +<<<<<<< HEAD mssqlVersion, err := parseMsSqlVersion(version) +======= + mssqlVersion, err := parseMSSqlVersion(version) +>>>>>>> ffcf962 (Adds MSSQL collector based on Postgres collector) if err != nil { databaseConnection.Version = "Unknown" databaseConnection.Error = err.Error() @@ -74,8 +98,13 @@ func (c *CollectMssql) Collect(progressChan chan<- interface{}) (CollectorResult return output, nil } +<<<<<<< HEAD func parseMsSqlVersion(mssqlVersion string) (string, error) { re := regexp.MustCompile(".*SQL.*-\\s+([0-9.]+)") +======= +func parseMSSqlVersion(mssqlVersion string) (string, error) { + re := regexp.MustCompile("MSSQLServer ([0-9.]*)") +>>>>>>> ffcf962 (Adds MSSQL collector based on Postgres collector) matches := re.FindStringSubmatch(mssqlVersion) if len(matches) < 2 { return "", errors.Errorf("mssql version did not match regex: %q", mssqlVersion) From 1026685be3c2d916202fa7dc8e4fb87dce26bd7c Mon Sep 17 00:00:00 2001 From: Chase Hainey Date: Wed, 22 Mar 2023 18:55:46 +0000 Subject: [PATCH 52/55] Missed a merge conflict. --- pkg/collect/mssql.go | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/pkg/collect/mssql.go b/pkg/collect/mssql.go index 443dd27bc..319cd16dc 100644 --- a/pkg/collect/mssql.go +++ b/pkg/collect/mssql.go @@ -15,17 +15,12 @@ import ( "k8s.io/client-go/rest" ) -<<<<<<< HEAD type CollectMssql struct { -======= -type CollectMSSql struct { ->>>>>>> ffcf962 (Adds MSSQL collector based on Postgres collector) Collector *troubleshootv1beta2.Database BundlePath string Namespace string ClientConfig *rest.Config Client kubernetes.Interface -<<<<<<< HEAD Context context.Context RBACErrors } @@ -39,21 +34,6 @@ func (c *CollectMssql) IsExcluded() (bool, error) { } func (c *CollectMssql) Collect(progressChan chan<- interface{}) (CollectorResult, error) { -======= - ctx context.Context - RBACErrors -} - -func (c *CollectMSSql) Title() string { - return collectorTitleOrDefault(c.Collector.CollectorMeta, "MSSSQLServer") -} - -func (c *CollectMSSql) IsExcluded() (bool, error) { - return isExcluded(c.Collector.Exclude) -} - -func (c *CollectMSSql) Collect(progressChan chan<- interface{}) (CollectorResult, error) { ->>>>>>> ffcf962 (Adds MSSQL collector based on Postgres collector) databaseConnection := DatabaseConnection{} db, err := sql.Open("mssql", c.Collector.URI) From bdf1bb4cc83bf275d95c8aa17d94612060d479c0 Mon Sep 17 00:00:00 2001 From: Chase Hainey Date: Wed, 22 Mar 2023 19:03:21 +0000 Subject: [PATCH 53/55] More merge conflicts fixed. --- pkg/collect/mssql.go | 9 --------- 1 file changed, 9 deletions(-) diff --git a/pkg/collect/mssql.go b/pkg/collect/mssql.go index 319cd16dc..d19387515 100644 --- a/pkg/collect/mssql.go +++ b/pkg/collect/mssql.go @@ -48,11 +48,7 @@ func (c *CollectMssql) Collect(progressChan chan<- interface{}) (CollectorResult } else { databaseConnection.IsConnected = true -<<<<<<< HEAD mssqlVersion, err := parseMsSqlVersion(version) -======= - mssqlVersion, err := parseMSSqlVersion(version) ->>>>>>> ffcf962 (Adds MSSQL collector based on Postgres collector) if err != nil { databaseConnection.Version = "Unknown" databaseConnection.Error = err.Error() @@ -78,13 +74,8 @@ func (c *CollectMssql) Collect(progressChan chan<- interface{}) (CollectorResult return output, nil } -<<<<<<< HEAD func parseMsSqlVersion(mssqlVersion string) (string, error) { re := regexp.MustCompile(".*SQL.*-\\s+([0-9.]+)") -======= -func parseMSSqlVersion(mssqlVersion string) (string, error) { - re := regexp.MustCompile("MSSQLServer ([0-9.]*)") ->>>>>>> ffcf962 (Adds MSSQL collector based on Postgres collector) matches := re.FindStringSubmatch(mssqlVersion) if len(matches) < 2 { return "", errors.Errorf("mssql version did not match regex: %q", mssqlVersion) From e96bf064bc4a4d9d4bf4eb57be399cae91d03329 Mon Sep 17 00:00:00 2001 From: Chase Hainey Date: Thu, 23 Mar 2023 19:53:29 +0000 Subject: [PATCH 54/55] Ran go mod tidy. --- go.mod | 7 +++---- go.sum | 22 +++------------------- 2 files changed, 6 insertions(+), 23 deletions(-) diff --git a/go.mod b/go.mod index e514cff13..d6fe2c811 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 @@ -56,15 +57,13 @@ require ( github.com/docker/distribution v2.8.1+incompatible // indirect github.com/emicklei/go-restful/v3 v3.9.0 // indirect github.com/evanphx/json-patch/v5 v5.6.0 // indirect - github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe // indirect - github.com/golang-sql/sqlexp v0.1.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 github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect - github.com/microsoft/go-mssqldb v0.18.0 // indirect github.com/mistifyio/go-zfs/v3 v3.0.0 // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect @@ -130,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 391bc44bb..59e7b82e4 100644 --- a/go.sum +++ b/go.sum @@ -607,8 +607,6 @@ 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.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= -github.com/golang-jwt/jwt/v4 v4.2.0 h1:besgBTC8w8HjP6NzQdxwKH9Z5oQMZ24ThTrHp3cZ8eU= 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= @@ -768,9 +766,6 @@ github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9 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.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go-version v1.3.0 h1:McDWVJIU/y+u1BRV06dPaLfLCaT7fUTJLp5r04x7iNw= -github.com/hashicorp/go-version v1.3.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= 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= @@ -798,10 +793,6 @@ 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/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg= -github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= -github.com/jackc/pgx/v5 v5.2.0 h1:NdPpngX0Y6z6XDFKqmFQaE+bCtkqzvQIOt1wvBlAqs8= -github.com/jackc/pgx/v5 v5.2.0/go.mod h1:Ptn7zmohNsWEsdxRawMzk3gaKma2obW+NWTnKa0S4nk= 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= @@ -1280,17 +1271,10 @@ golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm 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.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= -golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= -golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= -golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= -golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 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.0.0-20220919173607-35f4265a4bc0 h1:a5Yg6ylndHHYJqIPrdq0AhvR6KTvDTAvgBtaidhEevY= -golang.org/x/crypto v0.0.0-20220919173607-35f4265a4bc0/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8= -golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80= +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= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1544,7 +1528,6 @@ golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBc 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-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= @@ -1913,6 +1896,7 @@ 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= From da886ae3594b228c5ecd9a09f4193189e7559060 Mon Sep 17 00:00:00 2001 From: Chase Hainey Date: Thu, 23 Mar 2023 20:22:10 +0000 Subject: [PATCH 55/55] Fixed the function name return. --- pkg/collect/mssql.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/collect/mssql.go b/pkg/collect/mssql.go index d19387515..47b71f074 100644 --- a/pkg/collect/mssql.go +++ b/pkg/collect/mssql.go @@ -26,7 +26,7 @@ type CollectMssql struct { } func (c *CollectMssql) Title() string { - return collectorTitleOrDefault(c.Collector.CollectorMeta, "MSSSQLServer") + return getCollectorName(c) } func (c *CollectMssql) IsExcluded() (bool, error) {