From 60c639cb3b6c8ddff2eb57de72986780b42f907c Mon Sep 17 00:00:00 2001 From: Husni Mansour Date: Fri, 16 May 2025 11:06:50 +0200 Subject: [PATCH] Adding everything --- go.mod | 15 +- go.sum | 39 +++- internal/cli/opsmanager/advisor/advisor.go | 36 ++++ .../cli/opsmanager/advisor/upgrade/check.go | 170 ++++++++++++++++++ .../cli/opsmanager/advisor/upgrade/upgrade.go | 32 ++++ internal/cli/opsmanager/ops_manager.go | 4 +- internal/flag/flags.go | 1 + internal/store/advisor.go | 37 ++++ internal/usage/usage.go | 1 + 9 files changed, 328 insertions(+), 7 deletions(-) create mode 100644 internal/cli/opsmanager/advisor/advisor.go create mode 100644 internal/cli/opsmanager/advisor/upgrade/check.go create mode 100644 internal/cli/opsmanager/advisor/upgrade/upgrade.go create mode 100644 internal/store/advisor.go diff --git a/go.mod b/go.mod index 865a02af8..c9c24c9dc 100644 --- a/go.mod +++ b/go.mod @@ -4,12 +4,14 @@ go 1.24.1 require ( github.com/AlecAivazis/survey/v2 v2.3.7 + github.com/Delta456/box-cli-maker/v2 v2.3.0 github.com/Masterminds/semver/v3 v3.3.1 github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 github.com/PaesslerAG/jsonpath v0.1.1 github.com/briandowns/spinner v1.23.2 github.com/creack/pty v1.1.24 github.com/evergreen-ci/shrub v0.0.0-20240215220116-3f233ddeff2a + github.com/fatih/color v1.18.0 github.com/gemalto/kmip-go v0.0.10 github.com/go-test/deep v1.1.1 github.com/golang-jwt/jwt/v4 v4.5.2 @@ -20,6 +22,7 @@ require ( github.com/mattn/go-isatty v0.0.20 github.com/mongodb-forks/digest v1.1.0 github.com/mongodb-labs/cobra2snooty v1.19.1 + github.com/olekukonko/tablewriter v1.0.4 github.com/pelletier/go-toml v1.9.5 github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c github.com/spf13/afero v1.14.0 @@ -41,18 +44,24 @@ require ( github.com/ansel1/merry v1.6.2 // indirect github.com/ansel1/merry/v2 v2.0.1 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/fatih/color v1.15.0 // indirect github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/gemalto/flume v0.13.0 // indirect github.com/go-viper/mapstructure/v2 v2.2.1 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/uuid v1.6.0 // indirect + github.com/gookit/color v1.5.2 // indirect + github.com/huandu/xstrings v1.3.2 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-runewidth v0.0.16 // indirect github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect + github.com/muesli/reflow v0.3.0 // indirect + github.com/olekukonko/errors v0.0.0-20250405072817-4e6d85265da6 // indirect + github.com/olekukonko/ll v0.0.6-0.20250511102614-9564773e9d27 // indirect github.com/pelletier/go-toml/v2 v2.2.3 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/rivo/uniseg v0.4.7 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect github.com/sagikazarmark/locafero v0.7.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect @@ -60,6 +69,7 @@ require ( github.com/spf13/pflag v1.0.6 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/xdg-go/stringprep v1.0.4 // indirect + github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect go.uber.org/goleak v1.3.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect @@ -67,5 +77,6 @@ require ( golang.org/x/sys v0.33.0 // indirect golang.org/x/term v0.32.0 // indirect golang.org/x/text v0.25.0 // indirect - gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect ) + +replace go.mongodb.org/ops-manager => ../go-client-mongodb-ops-manager diff --git a/go.sum b/go.sum index 0bd3334d5..ac2757578 100644 --- a/go.sum +++ b/go.sum @@ -3,6 +3,8 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ= github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Delta456/box-cli-maker/v2 v2.3.0 h1:rGdoK/Qt3shdT1uqRMGgPqrhtisGD7PamTW8vY5MyCA= +github.com/Delta456/box-cli-maker/v2 v2.3.0/go.mod h1:Uv/kSX95LuNQn3C8wWazEIETE6MunPuYN+/knckbPQc= github.com/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7rj+4nv4= github.com/Masterminds/semver/v3 v3.3.1/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s= @@ -37,6 +39,7 @@ github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s= github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE= @@ -52,8 +55,8 @@ github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go. github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evergreen-ci/shrub v0.0.0-20240215220116-3f233ddeff2a h1:Hsu++nuXl8MvWhcxjQyyZtdJDv85kVrDVxf0LcUoAmQ= github.com/evergreen-ci/shrub v0.0.0-20240215220116-3f233ddeff2a/go.mod h1:r6YQr77CR37LMhBdWcFrxqu5V+UhO+SYloHfd9vO1go= -github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= -github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= +github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= +github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M= @@ -96,6 +99,7 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/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.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-github/v61 v61.0.0 h1:VwQCBwhyE9JclCI+22/7mLB1PuU9eowCXKY5pNlu1go= @@ -105,10 +109,14 @@ github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17 github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gookit/color v1.5.2 h1:uLnfXcaFjlrDnQDT+NCBcfhrXqYTx/rcCa6xn01Y8yI= +github.com/gookit/color v1.5.2/go.mod h1:w8h4bGiHeeBpvQVePTutdbERIUf3oJE5lZ8HM0UgXyg= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68= github.com/hinshun/vt10x v0.0.0-20220301184237-5011da428d02 h1:AgcIVYPa6XJnU3phs104wLj8l5GEththEw6+F79YsIY= github.com/hinshun/vt10x v0.0.0-20220301184237-5011da428d02/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68= +github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw= +github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= @@ -137,6 +145,10 @@ github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= +github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI= github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= @@ -144,6 +156,14 @@ github.com/mongodb-forks/digest v1.1.0 h1:7eUdsR1BtqLv0mdNm4OXs6ddWvR4X2/OsLwdKk github.com/mongodb-forks/digest v1.1.0/go.mod h1:rb+EX8zotClD5Dj4NdgxnJXG9nwrlx3NWKJ8xttz1Dg= github.com/mongodb-labs/cobra2snooty v1.19.1 h1:GDEQZWy8f/DeJlImNgVvStu6sgNi8nuSOR1Oskcw8BI= github.com/mongodb-labs/cobra2snooty v1.19.1/go.mod h1:Hyq4YadN8dwdOiz56MXwTuVN63p0WlkQwxdLxOSGdX8= +github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= +github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= +github.com/olekukonko/errors v0.0.0-20250405072817-4e6d85265da6 h1:r3FaAI0NZK3hSmtTDrBVREhKULp8oUeqLT5Eyl2mSPo= +github.com/olekukonko/errors v0.0.0-20250405072817-4e6d85265da6/go.mod h1:ppzxA5jBKcO1vIpCXQ9ZqgDh8iwODz6OXIGKU8r5m4Y= +github.com/olekukonko/ll v0.0.6-0.20250511102614-9564773e9d27 h1:LgDwLQDELPB6wMOx1x4DSXnH2pjQNDKFgqv2inJuiAU= +github.com/olekukonko/ll v0.0.6-0.20250511102614-9564773e9d27/go.mod h1:En+sEW0JNETl26+K8eZ6/W4UQ7CYSrrgg/EdIYT2H8g= +github.com/olekukonko/tablewriter v1.0.4 h1:Lnz32TW+q/MQhA4qwhIyLA+j5hZ3dcNpZrcpPC+4iaM= +github.com/olekukonko/tablewriter v1.0.4/go.mod h1:eUa4ArVhHJYomS27xrJB/GyLtnzKKVkZeLM6/MNO+pA= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= @@ -156,6 +176,10 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= @@ -175,12 +199,15 @@ github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/spf13/viper v1.20.1 h1:ZMi+z/lvLyPSCoNtFCpqjy0S4kPbirhpTMwl8BkW9X4= github.com/spf13/viper v1.20.1/go.mod h1:P9Mdzt1zoHIG8m2eZQinpiBjo6kCmZSKBClNNqjJvu4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 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.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= @@ -189,14 +216,15 @@ github.com/tangzero/inflector v1.0.0 h1:933dvPwRUUOAl98hyeeXuzFix3HwDt5j+45lleu8 github.com/tangzero/inflector v1.0.0/go.mod h1:OknKjAyDPCDzcWt0yOh2I7hqTukEdyyApcX3/KOhuXc= github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8= github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= +github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= +github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= +github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= 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= go.mongodb.org/atlas v0.38.0 h1:zfwymq20GqivGwxPZfypfUDry+WwMGVui97z1d8V4bU= go.mongodb.org/atlas v0.38.0/go.mod h1:DJYtM+vsEpPEMSkQzJnFHrT0sP7ev6cseZc/GGjJYG8= go.mongodb.org/mongo-driver v1.17.3 h1:TQyXhnsWfWtgAhMtOgtYHMTkZIfBTpMTsMnd9ZBeHxQ= go.mongodb.org/mongo-driver v1.17.3/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ= -go.mongodb.org/ops-manager v0.60.0 h1:bQ6y7JcH9aL+G0RcNfBi4y4VHKgO11g3lNJgPyIjuDE= -go.mongodb.org/ops-manager v0.60.0/go.mod h1:KSE1pHgeFv9+e/LWY/0QOqR8EJtzAHcd+IyEEkuPReU= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= @@ -217,6 +245,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8= golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E= +golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= @@ -267,6 +297,7 @@ golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= 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.0.0-20221017184919-83659145692c/go.mod h1:VTIZ7TEbF0BS9Sv9lPTvGbtW8i4z6GGbJBCM37uMCzY= golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg= golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/internal/cli/opsmanager/advisor/advisor.go b/internal/cli/opsmanager/advisor/advisor.go new file mode 100644 index 000000000..8bb4f5392 --- /dev/null +++ b/internal/cli/opsmanager/advisor/advisor.go @@ -0,0 +1,36 @@ +// Copyright 2020 MongoDB Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package advisor + +import ( + "github.com/mongodb/mongodb-cli/mongocli/v2/internal/cli" + "github.com/mongodb/mongodb-cli/mongocli/v2/internal/cli/opsmanager/advisor/upgrade" + "github.com/spf13/cobra" +) + +func Builder() *cobra.Command { + const use = "advisor" + cmd := &cobra.Command{ + Use: use, + Aliases: cli.GenerateAliases(use), + Short: "Get an advice regarding your ops manager.", + } + + cmd.AddCommand( + upgrade.Builder(), + ) + + return cmd +} diff --git a/internal/cli/opsmanager/advisor/upgrade/check.go b/internal/cli/opsmanager/advisor/upgrade/check.go new file mode 100644 index 000000000..6d4df432c --- /dev/null +++ b/internal/cli/opsmanager/advisor/upgrade/check.go @@ -0,0 +1,170 @@ +package upgrade + +import ( + "context" + "fmt" + "os" + "strings" + + "github.com/Delta456/box-cli-maker/v2" + "github.com/fatih/color" + "github.com/mongodb/mongodb-cli/mongocli/v2/internal/cli" + "github.com/mongodb/mongodb-cli/mongocli/v2/internal/config" + "github.com/mongodb/mongodb-cli/mongocli/v2/internal/flag" + "github.com/mongodb/mongodb-cli/mongocli/v2/internal/store" + "github.com/mongodb/mongodb-cli/mongocli/v2/internal/usage" + "github.com/olekukonko/tablewriter" + "github.com/olekukonko/tablewriter/renderer" + "github.com/olekukonko/tablewriter/tw" + "github.com/spf13/cobra" + "go.mongodb.org/ops-manager/opsmngr" +) + +type CheckOpts struct { + cli.OutputOpts + targetVersion string + store store.AdvisorUpgrade +} + +func (opts *CheckOpts) initStore(ctx context.Context) func() error { + return func() error { + var err error + opts.store, err = store.New(store.AuthenticatedPreset(config.Default()), store.WithContext(ctx)) + return err + } +} + +func (opts *CheckOpts) Run() error { + steps, err := opts.store.AdvisorUpgradeCheck(opts.targetVersion) + if err != nil { + return err + } + + printFullWidthWarning([]string{ + "IMPORTANT!", + "You must execute the upgrade IN ORDER.", + "", + "• Work step-by-step: finish Step 1 before starting Step 2,", + " finish Step 2 before starting Step 3, and so on.", + "• Inside each step follow the sequence shown in the table", + " (Operating-System → MongoDB → Ops Manager → Automation Agent).", + "• Do NOT skip, reorder, or run steps in parallel.", + }) + + for i, s := range *steps { + renderCheckOutput(i+1, &s) + } + + return nil +} + +// mongocli opsmanager advisor upgrade check --targetVersion version. +func CheckBuilder() *cobra.Command { + opts := &CheckOpts{} + cmd := &cobra.Command{ + Use: "check", + Short: "Checks if your system meets the requirements to upgrade to a certain Ops Manager version.", + PreRunE: func(cmd *cobra.Command, _ []string) error { + opts.OutWriter = cmd.OutOrStdout() + return opts.initStore(cmd.Context())() + }, + RunE: func(_ *cobra.Command, _ []string) error { + return opts.Run() + }, + } + + cmd.Flags().StringVar(&opts.targetVersion, flag.TargetVersion, "", usage.TargetVersion) + + return cmd +} + +func renderCheckOutput(n int, step *opsmngr.UpgradeCheckStep) { + + println("\n", color.New(color.FgYellow, color.Bold).Sprintf("Step %d", n)) + section := func(s string) string { return color.New(color.FgCyan, color.Bold).Sprint(s) } + current := func(s string) string { return color.New(color.FgHiRed).Sprint(s) } + target := func(s string) string { return color.New(color.FgHiGreen).Sprint(s) } + multi := func(h []string) string { return strings.Join(h, "\n") } + + tbl := tablewriter.NewTable(os.Stdout, + tablewriter.WithRenderer(renderer.NewBlueprint(tw.Rendition{ + Settings: tw.Settings{Separators: tw.Separators{BetweenRows: tw.On}}, + })), + tablewriter.WithConfig(tablewriter.Config{ + Row: tw.CellConfig{Formatting: tw.CellFormatting{ + MergeMode: tw.MergeBoth, Alignment: tw.AlignLeft, + }}, + }), + ) + arrow := "→" + + printOpsManager := func(blocks opsmngr.OpsManagerStep) { + tbl.Append([]string{section("Ops Manager"), section("Ops Manager")}) + tbl.Append([]string{"Version:", fmt.Sprintf("%s %s %s", current(step.OpsManager.CurrentVersion), arrow, target(step.OpsManager.TargetVersion))}) + tbl.Append([]string{color.New(color.FgMagenta, color.Bold).Sprint("Hosts Need to be upgraded:"), multi(step.OpsManager.Hosts)}) + } + + printOS := func(blocks []opsmngr.OperatingSystemStep) { + if len(blocks) == 0 { + return + } + for i, b := range blocks { + if i == 0 { + tbl.Append([]string{section("OS"), section("OS")}) + } + if b.BaseVersion != "" { + tbl.Append([]string{"Base Version:", b.BaseVersion}) + } + tbl.Append([]string{"Version:", fmt.Sprintf("%s %s %s", current(b.CurrentVersion), arrow, target(b.TargetVersion))}) + tbl.Append([]string{color.New(color.FgMagenta, color.Bold).Sprint("Hosts Need to be upgraded:"), multi(b.Hosts)}) + } + } + printMongo := func(blocks []opsmngr.MongoDBStep) { + if len(blocks) == 0 { + return + } + for i, b := range blocks { + if i == 0 { + tbl.Append([]string{section("MongoDB"), section("MongoDB")}) + } + tbl.Append([]string{"Version:", fmt.Sprintf("%s %s %s", current(b.CurrentVersion), arrow, target(b.TargetVersion))}) + tbl.Append([]string{color.New(color.FgMagenta, color.Bold).Sprint("Hosts Need to be upgraded:"), multi(b.Hosts)}) + } + } + printAgent := func(blocks []opsmngr.AgentStep) { + if len(blocks) == 0 { + return + } + for i, b := range blocks { + if i == 0 { + tbl.Append([]string{section("Automation Agent"), section("Automation Agent")}) + } + tbl.Append([]string{"Version:", fmt.Sprintf("%s %s %s", current(b.CurrentVersion), arrow, target(b.TargetVersion))}) + tbl.Append([]string{color.New(color.FgMagenta, color.Bold).Sprint("Hosts Need to be upgraded:"), multi(b.Hosts)}) + } + } + + printOS(step.OperatingSystem) + printMongo(step.MongoDB) + printOpsManager(step.OpsManager) + printAgent(step.Agent) + + tbl.Render() +} + +func printFullWidthWarning(lines []string) { + body := strings.Join(lines, "\n") + + // 3. configure and print the box + b := box.New(box.Config{ + Px: 1, + Py: 1, + Type: "Bold", + Color: "Yellow", + TitlePos: "Inside", + TitleColor: "Yellow", + ContentAlign: "Left", + }) + b.Print(" Notice ", body) + fmt.Println() // blank line after the box +} diff --git a/internal/cli/opsmanager/advisor/upgrade/upgrade.go b/internal/cli/opsmanager/advisor/upgrade/upgrade.go new file mode 100644 index 000000000..f867c8207 --- /dev/null +++ b/internal/cli/opsmanager/advisor/upgrade/upgrade.go @@ -0,0 +1,32 @@ +// Copyright 2021 MongoDB Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package upgrade + +import ( + "github.com/spf13/cobra" +) + +func Builder() *cobra.Command { + cmd := &cobra.Command{ + Use: "upgrade", + Short: "Manages your upgrade process of Ops Manager.", + } + + cmd.AddCommand( + CheckBuilder(), + ) + + return cmd +} diff --git a/internal/cli/opsmanager/ops_manager.go b/internal/cli/opsmanager/ops_manager.go index 702957270..c015ea9f3 100644 --- a/internal/cli/opsmanager/ops_manager.go +++ b/internal/cli/opsmanager/ops_manager.go @@ -19,6 +19,7 @@ import ( "github.com/mongodb/mongodb-cli/mongocli/v2/internal/cli/mongocli/events" "github.com/mongodb/mongodb-cli/mongocli/v2/internal/cli/mongocli/performanceadvisor" "github.com/mongodb/mongodb-cli/mongocli/v2/internal/cli/opsmanager/admin" + "github.com/mongodb/mongodb-cli/mongocli/v2/internal/cli/opsmanager/advisor" "github.com/mongodb/mongodb-cli/mongocli/v2/internal/cli/opsmanager/agents" "github.com/mongodb/mongodb-cli/mongocli/v2/internal/cli/opsmanager/automation" "github.com/mongodb/mongodb-cli/mongocli/v2/internal/cli/opsmanager/backup" @@ -93,7 +94,8 @@ func Builder() *cobra.Command { softwarecompotents.Builder(), featurepolicies.Builder(), serverusage.Builder(), - livemigrations.Builder()) + livemigrations.Builder(), + advisor.Builder()) cmd.PersistentFlags().BoolVarP(&debugLevel, flag.Debug, flag.DebugShort, false, usage.Debug) _ = cmd.PersistentFlags().MarkHidden(flag.Debug) diff --git a/internal/flag/flags.go b/internal/flag/flags.go index fff29f8cb..15460f46e 100644 --- a/internal/flag/flags.go +++ b/internal/flag/flags.go @@ -183,4 +183,5 @@ const ( KMIPClientCertificatePassword = "kmipClientCertificatePassword" //nolint:gosec // KMIPClientCertificatePassword flag KMIPUsername = "kmipUsername" // KMIPUsername flag KMIPPassword = "kmipPassword" // KMIPPassword flag + TargetVersion = "targetVersion" // TargetVersion flag ) diff --git a/internal/store/advisor.go b/internal/store/advisor.go new file mode 100644 index 000000000..077db3c1b --- /dev/null +++ b/internal/store/advisor.go @@ -0,0 +1,37 @@ +// Copyright 2020 MongoDB Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package store + +import ( + "fmt" + + "github.com/mongodb/mongodb-cli/mongocli/v2/internal/config" + "go.mongodb.org/ops-manager/opsmngr" +) + +type AdvisorUpgrade interface { + AdvisorUpgradeCheck(version string) (*[]opsmngr.UpgradeCheckStep, error) +} + +// AdvisorUpgradeCheck ... +func (s *Store) AdvisorUpgradeCheck(version string) (*[]opsmngr.UpgradeCheckStep, error) { + switch s.service { + case config.OpsManagerService: + result, _, err := s.client.Advisor.CheckUpgrade(s.ctx, version) + return result, err + default: + return nil, fmt.Errorf("%w: %s", errUnsupportedService, s.service) + } +} diff --git a/internal/usage/usage.go b/internal/usage/usage.go index f929714c9..cbeede53d 100644 --- a/internal/usage/usage.go +++ b/internal/usage/usage.go @@ -212,4 +212,5 @@ const ( Debug = "Debug log level." RequiredRole = "To use this command, you must authenticate with a user account or an API key with the %s role." UpdateWarning = " Passing this flag replaces preexisting data." + TargetVersion = " The version you want to upgrade to." )