From f32938260c6d6f5c35f428795655780f9f6859ce Mon Sep 17 00:00:00 2001 From: Oleg Isakov Date: Fri, 8 Aug 2025 14:28:27 +0300 Subject: [PATCH 1/5] bump pkgs --- go.mod | 47 ++++++++++------------ go.sum | 124 +++++++++++++++++++++++++-------------------------------- 2 files changed, 74 insertions(+), 97 deletions(-) diff --git a/go.mod b/go.mod index 2186b3c..b5857f9 100644 --- a/go.mod +++ b/go.mod @@ -5,37 +5,30 @@ go 1.23.0 require ( github.com/creack/pty v1.1.24 github.com/jmespath/go-jmespath v0.4.0 - github.com/onsi/gomega v1.36.2 - github.com/serverscom/serverscom-go-client v1.0.17 - github.com/spf13/cobra v1.8.1 - github.com/spf13/pflag v1.0.5 - github.com/spf13/viper v1.19.0 - github.com/stoewer/go-strcase v1.3.0 - go.uber.org/mock v0.5.0 - golang.org/x/term v0.32.0 - golang.org/x/text v0.25.0 + github.com/onsi/gomega v1.38.0 + github.com/serverscom/serverscom-go-client v1.0.18 + github.com/spf13/cobra v1.9.1 + github.com/spf13/pflag v1.0.7 + github.com/spf13/viper v1.20.1 + github.com/stoewer/go-strcase v1.3.1 + go.uber.org/mock v0.5.2 + golang.org/x/term v0.34.0 + golang.org/x/text v0.28.0 gopkg.in/yaml.v3 v3.0.1 ) require ( - github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/go-resty/resty/v2 v2.16.2 // indirect - github.com/google/go-cmp v0.6.0 // indirect - github.com/hashicorp/hcl v1.0.0 // indirect + github.com/fsnotify/fsnotify v1.9.0 // indirect + github.com/go-resty/resty/v2 v2.16.5 // indirect + github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/google/go-cmp v0.7.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/magiconair/properties v1.8.7 // indirect - github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/pelletier/go-toml/v2 v2.2.2 // indirect - github.com/sagikazarmark/locafero v0.4.0 // indirect - github.com/sagikazarmark/slog-shim v0.1.0 // indirect - github.com/sourcegraph/conc v0.3.0 // indirect - github.com/spf13/afero v1.11.0 // indirect - github.com/spf13/cast v1.6.0 // indirect + github.com/pelletier/go-toml/v2 v2.2.4 // indirect + github.com/sagikazarmark/locafero v0.10.0 // indirect + github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect + github.com/spf13/afero v1.14.0 // indirect + github.com/spf13/cast v1.9.2 // indirect github.com/subosito/gotenv v1.6.0 // indirect - go.uber.org/atomic v1.9.0 // indirect - go.uber.org/multierr v1.9.0 // indirect - golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect - golang.org/x/net v0.40.0 // indirect - golang.org/x/sys v0.33.0 // indirect - gopkg.in/ini.v1 v1.67.0 // indirect + golang.org/x/net v0.43.0 // indirect + golang.org/x/sys v0.35.0 // indirect ) diff --git a/go.sum b/go.sum index 7a2fca1..2df103c 100644 --- a/go.sum +++ b/go.sum @@ -1,26 +1,25 @@ -github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s= github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/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.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= -github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-resty/resty/v2 v2.16.2 h1:CpRqTjIzq/rweXUt9+GxzzQdlkqMdt8Lm/fuK/CAbAg= -github.com/go-resty/resty/v2 v2.16.2/go.mod h1:0fHAoK7JoBy/Ch36N8VFeMsK7xQOHhvWaC3iOktwmIU= +github.com/go-resty/resty/v2 v2.16.5 h1:hBKqmWrr7uRc3euHVqmh1HTHcKn99Smr7o5spptdhTM= +github.com/go-resty/resty/v2 v2.16.5/go.mod h1:hkJtXbA2iKHzJheXYvQ8snQES5ZLGKMwQ07xAwp/fiA= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= -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/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg= -github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= -github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= +github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8= +github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= @@ -31,80 +30,65 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= -github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= -github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= -github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/onsi/ginkgo/v2 v2.22.1 h1:QW7tbJAUDyVDVOM5dFa7qaybo+CRfR7bemlQUN6Z8aM= -github.com/onsi/ginkgo/v2 v2.22.1/go.mod h1:S6aTpoRsSq2cZOd+pssHAlKW/Q/jZt6cPrPlnj4a1xM= -github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8= -github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY= -github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= -github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= +github.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus= +github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8= +github.com/onsi/gomega v1.38.0 h1:c/WX+w8SLAinvuKKQFh77WEucCnPk4j2OTUr7lt7BeY= +github.com/onsi/gomega v1.38.0/go.mod h1:OcXcwId0b9QsE7Y49u+BTrL4IdKOBOKnD6VQNTJEB6o= +github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= +github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= -github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= -github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= -github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= -github.com/serverscom/serverscom-go-client v1.0.17 h1:noPj7s8G3CdnhfwHadMu7f0cqt+H9rpv01wjHHaoafs= -github.com/serverscom/serverscom-go-client v1.0.17/go.mod h1:/Nf+XygKOxm19Sl2gvMzT55O4X+tWDkj/UM4mjzfKgM= -github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= -github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= -github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= -github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= -github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= -github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= -github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= -github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= -github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= -github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs= -github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo= +github.com/sagikazarmark/locafero v0.10.0 h1:FM8Cv6j2KqIhM2ZK7HZjm4mpj9NBktLgowT1aN9q5Cc= +github.com/sagikazarmark/locafero v0.10.0/go.mod h1:Ieo3EUsjifvQu4NZwV5sPd4dwvu0OCgEQV7vjc9yDjw= +github.com/serverscom/serverscom-go-client v1.0.18 h1:GsPCStqUFWjzcMepaJDXjFUymx0W5DUNAoOXz2s7MVI= +github.com/serverscom/serverscom-go-client v1.0.18/go.mod h1:/Nf+XygKOxm19Sl2gvMzT55O4X+tWDkj/UM4mjzfKgM= +github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw= +github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U= +github.com/spf13/afero v1.14.0 h1:9tH6MapGnn/j0eb0yIXiLjERO8RB6xIVZRDCX7PtqWA= +github.com/spf13/afero v1.14.0/go.mod h1:acJQ8t0ohCGuMN3O+Pv0V0hgMxNYDlvdk+VTfyZmbYo= +github.com/spf13/cast v1.9.2 h1:SsGfm7M8QOFtEzumm7UZrZdLLquNdzFYfIbEXntcFbE= +github.com/spf13/cast v1.9.2/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= +github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= +github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= +github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.7 h1:vN6T9TfwStFPFM5XzjsvmzZkLuaLX+HS+0SeFLRgU6M= +github.com/spf13/pflag v1.0.7/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.20.1 h1:ZMi+z/lvLyPSCoNtFCpqjy0S4kPbirhpTMwl8BkW9X4= +github.com/spf13/viper v1.20.1/go.mod h1:P9Mdzt1zoHIG8m2eZQinpiBjo6kCmZSKBClNNqjJvu4= +github.com/stoewer/go-strcase v1.3.1 h1:iS0MdW+kVTxgMoE1LAZyMiYJFKlOzLooE4MxjirtkAs= +github.com/stoewer/go-strcase v1.3.1/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/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= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= -go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= -go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= -go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= -go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= -go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= -golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= -golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= -golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= -golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= -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.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg= -golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ= -golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= -golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= +go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= +go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8= +go.uber.org/mock v0.5.2 h1:LbtPTcP8A5k9WPXj54PPPbjcI4Y6lhyOZXn+VS7wNko= +go.uber.org/mock v0.5.2/go.mod h1:wLlUxC2vVTPTaE3UD51E0BGOAElKrILxhVSDYQLld5o= +golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= +golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= +golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4= +golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw= +golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= +golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8= -golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw= +golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0= +golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -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/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From 6b12ad16631a29d1c59ab873412b9d4bd4e61eff Mon Sep 17 00:00:00 2001 From: Oleg Isakov Date: Fri, 8 Aug 2025 14:28:49 +0300 Subject: [PATCH 2/5] update mocks --- internal/mocks/hosts_service.go | 98 +++++++++++++++++++++++++++++++-- 1 file changed, 94 insertions(+), 4 deletions(-) diff --git a/internal/mocks/hosts_service.go b/internal/mocks/hosts_service.go index 1c12619..3897150 100644 --- a/internal/mocks/hosts_service.go +++ b/internal/mocks/hosts_service.go @@ -56,6 +56,51 @@ func (mr *MockHostsServiceMockRecorder) AbortReleaseForDedicatedServer(ctx, id a return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AbortReleaseForDedicatedServer", reflect.TypeOf((*MockHostsService)(nil).AbortReleaseForDedicatedServer), ctx, id) } +// ActivateDedicatedServerPubliIPv6Network mocks base method. +func (m *MockHostsService) ActivateDedicatedServerPubliIPv6Network(ctx context.Context, id string) (*serverscom.Network, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ActivateDedicatedServerPubliIPv6Network", ctx, id) + ret0, _ := ret[0].(*serverscom.Network) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ActivateDedicatedServerPubliIPv6Network indicates an expected call of ActivateDedicatedServerPubliIPv6Network. +func (mr *MockHostsServiceMockRecorder) ActivateDedicatedServerPubliIPv6Network(ctx, id any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ActivateDedicatedServerPubliIPv6Network", reflect.TypeOf((*MockHostsService)(nil).ActivateDedicatedServerPubliIPv6Network), ctx, id) +} + +// AddDedicatedServerPrivateIPv4Network mocks base method. +func (m *MockHostsService) AddDedicatedServerPrivateIPv4Network(ctx context.Context, id string, input serverscom.NetworkInput) (*serverscom.Network, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AddDedicatedServerPrivateIPv4Network", ctx, id, input) + ret0, _ := ret[0].(*serverscom.Network) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// AddDedicatedServerPrivateIPv4Network indicates an expected call of AddDedicatedServerPrivateIPv4Network. +func (mr *MockHostsServiceMockRecorder) AddDedicatedServerPrivateIPv4Network(ctx, id, input any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddDedicatedServerPrivateIPv4Network", reflect.TypeOf((*MockHostsService)(nil).AddDedicatedServerPrivateIPv4Network), ctx, id, input) +} + +// AddDedicatedServerPublicIPv4Network mocks base method. +func (m *MockHostsService) AddDedicatedServerPublicIPv4Network(ctx context.Context, id string, input serverscom.NetworkInput) (*serverscom.Network, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AddDedicatedServerPublicIPv4Network", ctx, id, input) + ret0, _ := ret[0].(*serverscom.Network) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// AddDedicatedServerPublicIPv4Network indicates an expected call of AddDedicatedServerPublicIPv4Network. +func (mr *MockHostsServiceMockRecorder) AddDedicatedServerPublicIPv4Network(ctx, id, input any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddDedicatedServerPublicIPv4Network", reflect.TypeOf((*MockHostsService)(nil).AddDedicatedServerPublicIPv4Network), ctx, id, input) +} + // Collection mocks base method. func (m *MockHostsService) Collection() serverscom.Collection[serverscom.Host] { m.ctrl.T.Helper() @@ -186,18 +231,33 @@ func (mr *MockHostsServiceMockRecorder) DedicatedServerPowerFeeds(ctx, id any) * return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DedicatedServerPowerFeeds", reflect.TypeOf((*MockHostsService)(nil).DedicatedServerPowerFeeds), ctx, id) } +// DeleteDedicatedServerNetwork mocks base method. +func (m *MockHostsService) DeleteDedicatedServerNetwork(ctx context.Context, serverID, networkID string) (*serverscom.Network, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteDedicatedServerNetwork", ctx, serverID, networkID) + ret0, _ := ret[0].(*serverscom.Network) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteDedicatedServerNetwork indicates an expected call of DeleteDedicatedServerNetwork. +func (mr *MockHostsServiceMockRecorder) DeleteDedicatedServerNetwork(ctx, serverID, networkID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteDedicatedServerNetwork", reflect.TypeOf((*MockHostsService)(nil).DeleteDedicatedServerNetwork), ctx, serverID, networkID) +} + // DeletePTRRecordForDedicatedServer mocks base method. -func (m *MockHostsService) DeletePTRRecordForDedicatedServer(ctx context.Context, hostID, ptrRecordID string) error { +func (m *MockHostsService) DeletePTRRecordForDedicatedServer(ctx context.Context, serverID, ptrRecordID string) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DeletePTRRecordForDedicatedServer", ctx, hostID, ptrRecordID) + ret := m.ctrl.Call(m, "DeletePTRRecordForDedicatedServer", ctx, serverID, ptrRecordID) ret0, _ := ret[0].(error) return ret0 } // DeletePTRRecordForDedicatedServer indicates an expected call of DeletePTRRecordForDedicatedServer. -func (mr *MockHostsServiceMockRecorder) DeletePTRRecordForDedicatedServer(ctx, hostID, ptrRecordID any) *gomock.Call { +func (mr *MockHostsServiceMockRecorder) DeletePTRRecordForDedicatedServer(ctx, serverID, ptrRecordID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePTRRecordForDedicatedServer", reflect.TypeOf((*MockHostsService)(nil).DeletePTRRecordForDedicatedServer), ctx, hostID, ptrRecordID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePTRRecordForDedicatedServer", reflect.TypeOf((*MockHostsService)(nil).DeletePTRRecordForDedicatedServer), ctx, serverID, ptrRecordID) } // GetDedicatedServer mocks base method. @@ -215,6 +275,36 @@ func (mr *MockHostsServiceMockRecorder) GetDedicatedServer(ctx, id any) *gomock. return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDedicatedServer", reflect.TypeOf((*MockHostsService)(nil).GetDedicatedServer), ctx, id) } +// GetDedicatedServerNetwork mocks base method. +func (m *MockHostsService) GetDedicatedServerNetwork(ctx context.Context, serverID, networkID string) (*serverscom.Network, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetDedicatedServerNetwork", ctx, serverID, networkID) + ret0, _ := ret[0].(*serverscom.Network) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetDedicatedServerNetwork indicates an expected call of GetDedicatedServerNetwork. +func (mr *MockHostsServiceMockRecorder) GetDedicatedServerNetwork(ctx, serverID, networkID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDedicatedServerNetwork", reflect.TypeOf((*MockHostsService)(nil).GetDedicatedServerNetwork), ctx, serverID, networkID) +} + +// GetDedicatedServerNetworkUsage mocks base method. +func (m *MockHostsService) GetDedicatedServerNetworkUsage(ctx context.Context, id string) (*serverscom.NetworkUsage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetDedicatedServerNetworkUsage", ctx, id) + ret0, _ := ret[0].(*serverscom.NetworkUsage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetDedicatedServerNetworkUsage indicates an expected call of GetDedicatedServerNetworkUsage. +func (mr *MockHostsServiceMockRecorder) GetDedicatedServerNetworkUsage(ctx, id any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDedicatedServerNetworkUsage", reflect.TypeOf((*MockHostsService)(nil).GetDedicatedServerNetworkUsage), ctx, id) +} + // GetKubernetesBaremetalNode mocks base method. func (m *MockHostsService) GetKubernetesBaremetalNode(ctx context.Context, id string) (*serverscom.KubernetesBaremetalNode, error) { m.ctrl.T.Helper() From dee43de954b8d29057dd89d1ea3180f847d69147 Mon Sep 17 00:00:00 2001 From: Oleg Isakov Date: Fri, 8 Aug 2025 14:30:19 +0300 Subject: [PATCH 3/5] add ds networks cmds --- cmd/entities/hosts/hosts.go | 4 + cmd/entities/hosts/networks.go | 151 ++++++++++++++++++++++++++++++ cmd/entities/hosts/validate.go | 40 ++++++++ internal/output/entities/hosts.go | 20 ++++ 4 files changed, 215 insertions(+) create mode 100644 cmd/entities/hosts/networks.go create mode 100644 cmd/entities/hosts/validate.go diff --git a/cmd/entities/hosts/hosts.go b/cmd/entities/hosts/hosts.go index ce68792..eb5a0f5 100644 --- a/cmd/entities/hosts/hosts.go +++ b/cmd/entities/hosts/hosts.go @@ -50,6 +50,10 @@ func NewCmd(cmdContext *base.CmdContext) *cobra.Command { newListDSPTRCmd, newDSAbortReleaseCmd, newDSScheduleReleaseCmd, + newListDSNetworksCmd, + newGetDSNetworkCmd, + newAddDSNetworkCmd, + newDeleteDSNetworkCmd, }, }, { diff --git a/cmd/entities/hosts/networks.go b/cmd/entities/hosts/networks.go new file mode 100644 index 0000000..59c0387 --- /dev/null +++ b/cmd/entities/hosts/networks.go @@ -0,0 +1,151 @@ +package hosts + +import ( + "log" + + serverscom "github.com/serverscom/serverscom-go-client/pkg" + "github.com/serverscom/srvctl/cmd/base" + "github.com/spf13/cobra" +) + +func newListDSNetworksCmd(cmdContext *base.CmdContext) *cobra.Command { + factory := func(verbose bool, args ...string) serverscom.Collection[serverscom.Network] { + scClient := cmdContext.GetClient().SetVerbose(verbose).GetScClient() + if len(args) == 0 { + log.Fatal("Missing dedicated server ID") + } + id := args[0] + return scClient.Hosts.DedicatedServerNetworks(id) + } + + opts := &base.BaseListOptions[serverscom.Network]{} + + return base.NewListCmd("list-networks ", "Dedicated server networks", factory, cmdContext, opts) +} + +func newGetDSNetworkCmd(cmdContext *base.CmdContext) *cobra.Command { + var networkID string + + cmd := &cobra.Command{ + Use: "get-network ", + Short: ("Get a dedicated server network"), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + manager := cmdContext.GetManager() + ctx, cancel := base.SetupContext(cmd, manager) + defer cancel() + + base.SetupProxy(cmd, manager) + scClient := cmdContext.GetClient().SetVerbose(manager.GetVerbose(cmd)).GetScClient() + + id := args[0] + entity, err := scClient.Hosts.GetDedicatedServerNetwork(ctx, id, networkID) + if err != nil { + return err + } + + if entity != nil { + formatter := cmdContext.GetOrCreateFormatter(cmd) + return formatter.Format(entity) + } + return nil + }, + } + + cmd.Flags().StringVar(&networkID, "network-id", "", "Network id (required)") + _ = cmd.MarkFlagRequired("network-id") + + return cmd +} + +func newAddDSNetworkCmd(cmdContext *base.CmdContext) *cobra.Command { + var ( + networkType string + mask int + distributionMethod string + ) + + cmd := &cobra.Command{ + Use: "add-network ", + Short: "Add private/public IPv4 network to dedicated server", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + id := args[0] + + if err := validateNetworkArgs(networkType, distributionMethod, mask); err != nil { + return err + } + + input := serverscom.NetworkInput{ + DistributionMethod: distributionMethod, + Mask: mask, + } + + manager := cmdContext.GetManager() + ctx, cancel := base.SetupContext(cmd, manager) + defer cancel() + base.SetupProxy(cmd, manager) + scClient := cmdContext.GetClient().SetVerbose(manager.GetVerbose(cmd)).GetScClient() + + var entity *serverscom.Network + var err error + switch networkType { + case "public": + entity, err = scClient.Hosts.AddDedicatedServerPublicIPv4Network(ctx, id, input) + case "private": + entity, err = scClient.Hosts.AddDedicatedServerPrivateIPv4Network(ctx, id, input) + } + if err != nil { + return err + } + if entity != nil { + formatter := cmdContext.GetOrCreateFormatter(cmd) + return formatter.Format(entity) + } + return nil + }, + } + + cmd.Flags().StringVar(&networkType, "type", "", "Network type: 'public' or 'private'") + cmd.Flags().IntVar(&mask, "mask", 0, "Network mask (required)") + cmd.Flags().StringVar(&distributionMethod, "distribution-method", "gateway", "Distribution method ('gateway' or 'route')") + _ = cmd.MarkFlagRequired("type") + _ = cmd.MarkFlagRequired("mask") + + return cmd +} + +func newDeleteDSNetworkCmd(cmdContext *base.CmdContext) *cobra.Command { + var networkID string + + cmd := &cobra.Command{ + Use: "delete-network ", + Short: ("Delete a dedicated server network"), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + manager := cmdContext.GetManager() + ctx, cancel := base.SetupContext(cmd, manager) + defer cancel() + + base.SetupProxy(cmd, manager) + scClient := cmdContext.GetClient().SetVerbose(manager.GetVerbose(cmd)).GetScClient() + + id := args[0] + entity, err := scClient.Hosts.DeleteDedicatedServerNetwork(ctx, id, networkID) + if err != nil { + return err + } + + if entity != nil { + formatter := cmdContext.GetOrCreateFormatter(cmd) + return formatter.Format(entity) + } + return nil + }, + } + + cmd.Flags().StringVar(&networkID, "network-id", "", "Network id (required)") + _ = cmd.MarkFlagRequired("network-id") + + return cmd +} diff --git a/cmd/entities/hosts/validate.go b/cmd/entities/hosts/validate.go new file mode 100644 index 0000000..3fdf059 --- /dev/null +++ b/cmd/entities/hosts/validate.go @@ -0,0 +1,40 @@ +package hosts + +import "fmt" + +var isValidMask = func(m int) bool { return m >= 26 && m <= 29 } + +func validateNetworkArgs(networkType, distributionMethod string, mask int) error { + if networkType != "public" && networkType != "private" { + return fmt.Errorf("--type must be 'public' or 'private'") + } + + if networkType == "private" { + if distributionMethod != "gateway" { + return fmt.Errorf("--distribution-method for private network can only be 'gateway'") + } + if !isValidMask(mask) { + return fmt.Errorf("--mask for private network must be: 26, 27, 28, or 29") + } + return nil + } + + if networkType == "public" { + switch distributionMethod { + case "gateway": + if !isValidMask(mask) { + return fmt.Errorf("--mask for public network (gateway) must be: 26, 27, 28, or 29") + } + return nil + case "route": + if mask != 32 { + return fmt.Errorf("--mask for public network with distribution-method='route' must be 32") + } + return nil + default: + return fmt.Errorf("--distribution-method for public network must be 'gateway' or 'route'") + } + } + + return nil +} diff --git a/internal/output/entities/hosts.go b/internal/output/entities/hosts.go index 4807221..b2b60ea 100644 --- a/internal/output/entities/hosts.go +++ b/internal/output/entities/hosts.go @@ -16,6 +16,7 @@ var ( HostPowerFeedType = reflect.TypeOf(serverscom.HostPowerFeed{}) HostDriveSlotType = reflect.TypeOf(serverscom.HostDriveSlot{}) HostPTRRecordType = reflect.TypeOf(serverscom.PTRRecord{}) + HostNetworkType = reflect.TypeOf(serverscom.Network{}) HostListDefaultFields = []string{"ID", "Type", "Title", "Status"} CmdDefaultFields = map[string][]string{ "list": HostListDefaultFields, @@ -243,4 +244,23 @@ func RegisterHostsSubDefinitions() { log.Fatal(err) } + hostNetworkEntity := &Entity{ + fields: []Field{ + {ID: "ID", Name: "ID", Path: "ID", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, + {ID: "Title", Name: "Title", Path: "Title", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, + {ID: "Status", Name: "Status", Path: "Status", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, + {ID: "CIDR", Name: "CIDR", Path: "Cidr", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, + {ID: "Family", Name: "Family", Path: "Family", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, + {ID: "InterfaceType", Name: "InterfaceType", Path: "InterfaceType", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, + {ID: "DistributionMethod", Name: "DistributionMethod", Path: "DistributionMethod", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, + {ID: "Additional", Name: "Additional", Path: "Additional", ListHandlerFunc: stringHandler, PageViewHandlerFunc: stringHandler, Default: true}, + {ID: "Updated", Name: "Updated", Path: "Updated", ListHandlerFunc: timeHandler, PageViewHandlerFunc: timeHandler, Default: true}, + {ID: "Created", Name: "Created", Path: "Created", ListHandlerFunc: timeHandler, PageViewHandlerFunc: timeHandler, Default: true}, + }, + eType: HostNetworkType, + } + if err := Registry.Register(hostNetworkEntity); err != nil { + log.Fatal(err) + } + } From e24119e9e56fca7b654f066a8bce9518677d6c71 Mon Sep 17 00:00:00 2001 From: Oleg Isakov Date: Fri, 8 Aug 2025 14:30:39 +0300 Subject: [PATCH 4/5] add tests for ds networks --- cmd/entities/hosts/hosts_test.go | 410 ++++++++++++++++++ testdata/entities/hosts/get_ds_network.json | 13 + testdata/entities/hosts/get_ds_network.txt | 2 + testdata/entities/hosts/get_ds_network.yaml | 11 + testdata/entities/hosts/list_ds_networks.json | 15 + .../entities/hosts/list_ds_networks_all.json | 28 ++ .../hosts/list_ds_networks_pageview.txt | 21 + .../hosts/list_ds_networks_template.txt | 2 + 8 files changed, 502 insertions(+) create mode 100644 testdata/entities/hosts/get_ds_network.json create mode 100644 testdata/entities/hosts/get_ds_network.txt create mode 100644 testdata/entities/hosts/get_ds_network.yaml create mode 100644 testdata/entities/hosts/list_ds_networks.json create mode 100644 testdata/entities/hosts/list_ds_networks_all.json create mode 100644 testdata/entities/hosts/list_ds_networks_pageview.txt create mode 100644 testdata/entities/hosts/list_ds_networks_template.txt diff --git a/cmd/entities/hosts/hosts_test.go b/cmd/entities/hosts/hosts_test.go index 2989874..009dce5 100644 --- a/cmd/entities/hosts/hosts_test.go +++ b/cmd/entities/hosts/hosts_test.go @@ -15,6 +15,7 @@ import ( var ( testId = "testId" + testNetworkId = "testNetId" fixtureBasePath = filepath.Join("..", "..", "..", "testdata", "entities", "hosts") fixedTime = time.Date(2025, 1, 1, 12, 0, 0, 0, time.UTC) testHost = serverscom.Host{ @@ -54,6 +55,20 @@ var ( Created: fixedTime, Updated: fixedTime, } + netTitle = "Some Net" + cidr = "100.0.8.0/29" + testDSNetwork = serverscom.Network{ + ID: testNetworkId, + Title: &netTitle, + Status: "active", + Cidr: &cidr, + Family: "ipv4", + InterfaceType: "public", + DistributionMethod: "gateway", + Additional: false, + Created: fixedTime, + Updated: fixedTime, + } ) func TestAddDSCmd(t *testing.T) { @@ -1402,3 +1417,398 @@ func TestReleaseSBMCmd(t *testing.T) { }) } } + +func TestGetDSNetworkCmd(t *testing.T) { + testCases := []struct { + name string + id string + networkID string + output string + expectedOutput []byte + expectError bool + }{ + { + name: "get DS network in default format", + id: testId, + networkID: testNetworkId, + output: "", + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "get_ds_network.txt")), + }, + { + name: "get DS network in JSON format", + id: testId, + networkID: testNetworkId, + output: "json", + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "get_ds_network.json")), + }, + { + name: "get DS network in YAML format", + id: testId, + networkID: testNetworkId, + output: "yaml", + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "get_ds_network.yaml")), + }, + { + name: "get DS network with error", + id: testId, + networkID: testNetworkId, + expectError: true, + }, + } + + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + hostsServiceHandler := mocks.NewMockHostsService(mockCtrl) + scClient := serverscom.NewClientWithEndpoint("", "") + scClient.Hosts = hostsServiceHandler + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + g := NewWithT(t) + + var err error + if tc.expectError { + err = errors.New("some error") + } + hostsServiceHandler.EXPECT(). + GetDedicatedServerNetwork(gomock.Any(), tc.id, tc.networkID). + Return(&testDSNetwork, err) + + testCmdContext := testutils.NewTestCmdContext(scClient) + hostsCmd := NewCmd(testCmdContext) + + args := []string{ + "hosts", "ds", "get-network", tc.id, + "--network-id", tc.networkID, + } + if tc.output != "" { + args = append(args, "--output", tc.output) + } + + builder := testutils.NewTestCommandBuilder(). + WithCommand(hostsCmd). + WithArgs(args) + + cmd := builder.Build() + err = cmd.Execute() + + if tc.expectError { + g.Expect(err).To(HaveOccurred()) + } else { + g.Expect(err).To(BeNil()) + g.Expect(builder.GetOutput()).To(BeEquivalentTo(string(tc.expectedOutput))) + } + }) + } +} + +func TestListDSNetworksCmd(t *testing.T) { + testNetwork1 := testDSNetwork + testNetwork1.ID = testNetworkId + testNetwork2 := testNetwork1 + testNetwork2.ID = "testNetId2" + netTitle2 := "Another Net" + testNetwork2.Title = &netTitle2 + + testCases := []struct { + name string + output string + args []string + expectedOutput []byte + expectError bool + configureMock func(*mocks.MockCollection[serverscom.Network]) + }{ + { + name: "list all DS networks", + output: "json", + args: []string{"testServerId", "-A"}, + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "list_ds_networks_all.json")), + configureMock: func(mock *mocks.MockCollection[serverscom.Network]) { + mock.EXPECT(). + Collect(gomock.Any()). + Return([]serverscom.Network{ + testNetwork1, + testNetwork2, + }, nil) + }, + }, + { + name: "list DS networks", + output: "json", + args: []string{"testServerId"}, + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "list_ds_networks.json")), + configureMock: func(mock *mocks.MockCollection[serverscom.Network]) { + mock.EXPECT(). + List(gomock.Any()). + Return([]serverscom.Network{ + testNetwork1, + }, nil) + }, + }, + { + name: "list DS networks with template", + args: []string{"testServerId", "--template", "{{range .}}Network: {{.ID}} Title: {{.Title}}\n{{end}}"}, + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "list_ds_networks_template.txt")), + configureMock: func(mock *mocks.MockCollection[serverscom.Network]) { + mock.EXPECT(). + List(gomock.Any()). + Return([]serverscom.Network{ + testNetwork1, + testNetwork2, + }, nil) + }, + }, + { + name: "list DS networks with pageView", + args: []string{"testServerId", "--page-view"}, + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "list_ds_networks_pageview.txt")), + configureMock: func(mock *mocks.MockCollection[serverscom.Network]) { + mock.EXPECT(). + List(gomock.Any()). + Return([]serverscom.Network{ + testNetwork1, + testNetwork2, + }, nil) + }, + }, + { + name: "list DS networks with error", + args: []string{"testServerId"}, + expectError: true, + configureMock: func(mock *mocks.MockCollection[serverscom.Network]) { + mock.EXPECT(). + List(gomock.Any()). + Return(nil, errors.New("some error")) + }, + }, + } + + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + hostsServiceHandler := mocks.NewMockHostsService(mockCtrl) + collectionHandler := mocks.NewMockCollection[serverscom.Network](mockCtrl) + + hostsServiceHandler.EXPECT(). + DedicatedServerNetworks(gomock.Any()). + Return(collectionHandler). + AnyTimes() + + collectionHandler.EXPECT(). + SetParam(gomock.Any(), gomock.Any()). + Return(collectionHandler). + AnyTimes() + + scClient := serverscom.NewClientWithEndpoint("", "") + scClient.Hosts = hostsServiceHandler + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + g := NewWithT(t) + + if tc.configureMock != nil { + tc.configureMock(collectionHandler) + } + + testCmdContext := testutils.NewTestCmdContext(scClient) + hostsCmd := NewCmd(testCmdContext) + + args := []string{"hosts", "ds", "list-networks"} + if len(tc.args) > 0 { + args = append(args, tc.args...) + } + if tc.output != "" { + args = append(args, "--output", tc.output) + } + + builder := testutils.NewTestCommandBuilder(). + WithCommand(hostsCmd). + WithArgs(args) + + cmd := builder.Build() + + err := cmd.Execute() + + if tc.expectError { + g.Expect(err).To(HaveOccurred()) + } else { + g.Expect(err).To(BeNil()) + g.Expect(builder.GetOutput()).To(BeEquivalentTo(string(tc.expectedOutput))) + } + }) + } +} + +func TestAddDSNetworkCmd(t *testing.T) { + expectedInputPublic := serverscom.NetworkInput{ + DistributionMethod: "route", + Mask: 32, + } + expectedInputPrivate := serverscom.NetworkInput{ + DistributionMethod: "gateway", + Mask: 29, + } + + testCases := []struct { + name string + output string + args []string + configureMock func(*mocks.MockHostsService) + expectedOutput []byte + expectError bool + }{ + { + name: "add public DS network", + output: "json", + args: []string{ + testId, + "--type", "public", + "--mask", "32", + "--distribution-method", "route", + }, + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "get_ds_network.json")), + configureMock: func(mock *mocks.MockHostsService) { + mock.EXPECT(). + AddDedicatedServerPublicIPv4Network(gomock.Any(), testId, expectedInputPublic). + Return(&testDSNetwork, nil) + }, + }, + { + name: "add private DS network", + output: "json", + args: []string{ + testId, + "--type", "private", + "--mask", "29", + "--distribution-method", "gateway", + }, + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "get_ds_network.json")), + configureMock: func(mock *mocks.MockHostsService) { + mock.EXPECT(). + AddDedicatedServerPrivateIPv4Network(gomock.Any(), testId, expectedInputPrivate). + Return(&testDSNetwork, nil) + }, + }, + { + name: "add DS network with unsupported mask", + args: []string{ + testId, + "--type", "public", + "--mask", "24", + "--distribution-method", "gateway", + }, + expectError: true, + }, + } + + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + hostsServiceHandler := mocks.NewMockHostsService(mockCtrl) + + scClient := serverscom.NewClientWithEndpoint("", "") + scClient.Hosts = hostsServiceHandler + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + g := NewWithT(t) + + if tc.configureMock != nil { + tc.configureMock(hostsServiceHandler) + } + + testCmdContext := testutils.NewTestCmdContext(scClient) + hostsCmd := NewCmd(testCmdContext) + + args := append([]string{"hosts", "ds", "add-network"}, tc.args...) + if tc.output != "" { + args = append(args, "--output", tc.output) + } + + builder := testutils.NewTestCommandBuilder(). + WithCommand(hostsCmd). + WithArgs(args) + + cmd := builder.Build() + + err := cmd.Execute() + + if tc.expectError { + g.Expect(err).To(HaveOccurred()) + } else { + g.Expect(err).To(BeNil()) + g.Expect(builder.GetOutput()).To(BeEquivalentTo(string(tc.expectedOutput))) + } + }) + } +} + +func TestDeleteDSNetworkCmd(t *testing.T) { + testCases := []struct { + name string + id string + networkID string + output string + expectedOutput []byte + expectError bool + }{ + { + name: "delete DS network", + id: testId, + networkID: testNetworkId, + output: "json", + expectedOutput: testutils.ReadFixture(filepath.Join(fixtureBasePath, "get_ds_network.json")), + }, + { + name: "delete DS network with error", + id: testId, + networkID: testNetworkId, + expectError: true, + }, + } + + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + hostsServiceHandler := mocks.NewMockHostsService(mockCtrl) + + scClient := serverscom.NewClientWithEndpoint("", "") + scClient.Hosts = hostsServiceHandler + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + g := NewWithT(t) + + var err error + if tc.expectError { + err = errors.New("some error") + } + hostsServiceHandler.EXPECT(). + DeleteDedicatedServerNetwork(gomock.Any(), tc.id, tc.networkID). + Return(&testDSNetwork, err) + + testCmdContext := testutils.NewTestCmdContext(scClient) + hostsCmd := NewCmd(testCmdContext) + + args := []string{"hosts", "ds", "delete-network", tc.id, "--network-id", tc.networkID} + if tc.output != "" { + args = append(args, "--output", tc.output) + } + + builder := testutils.NewTestCommandBuilder(). + WithCommand(hostsCmd). + WithArgs(args) + + cmd := builder.Build() + err = cmd.Execute() + + if tc.expectError { + g.Expect(err).To(HaveOccurred()) + } else { + g.Expect(err).To(BeNil()) + g.Expect(builder.GetOutput()).To(BeEquivalentTo(string(tc.expectedOutput))) + } + }) + } +} diff --git a/testdata/entities/hosts/get_ds_network.json b/testdata/entities/hosts/get_ds_network.json new file mode 100644 index 0000000..7e8137b --- /dev/null +++ b/testdata/entities/hosts/get_ds_network.json @@ -0,0 +1,13 @@ +{ + "id": "testNetId", + "title": "Some Net", + "status": "active", + "cidr": "100.0.8.0/29", + "family": "ipv4", + "interface_type": "public", + "distribution_method": "gateway", + "additional": false, + "created_at": "2025-01-01T12:00:00Z", + "updated_at": "2025-01-01T12:00:00Z", + "state": "" +} \ No newline at end of file diff --git a/testdata/entities/hosts/get_ds_network.txt b/testdata/entities/hosts/get_ds_network.txt new file mode 100644 index 0000000..92698fb --- /dev/null +++ b/testdata/entities/hosts/get_ds_network.txt @@ -0,0 +1,2 @@ +ID Title Status CIDR Family InterfaceType DistributionMethod Additional Updated Created +testNetId Some Net active 100.0.8.0/29 ipv4 public gateway false 2025-01-01T12:00:00Z 2025-01-01T12:00:00Z diff --git a/testdata/entities/hosts/get_ds_network.yaml b/testdata/entities/hosts/get_ds_network.yaml new file mode 100644 index 0000000..130e2cc --- /dev/null +++ b/testdata/entities/hosts/get_ds_network.yaml @@ -0,0 +1,11 @@ +id: testNetId +title: Some Net +status: active +cidr: 100.0.8.0/29 +family: ipv4 +interfacetype: public +distributionmethod: gateway +additional: false +created: 2025-01-01T12:00:00Z +updated: 2025-01-01T12:00:00Z +state: "" diff --git a/testdata/entities/hosts/list_ds_networks.json b/testdata/entities/hosts/list_ds_networks.json new file mode 100644 index 0000000..b024e7f --- /dev/null +++ b/testdata/entities/hosts/list_ds_networks.json @@ -0,0 +1,15 @@ +[ + { + "id": "testNetId", + "title": "Some Net", + "status": "active", + "cidr": "100.0.8.0/29", + "family": "ipv4", + "interface_type": "public", + "distribution_method": "gateway", + "additional": false, + "created_at": "2025-01-01T12:00:00Z", + "updated_at": "2025-01-01T12:00:00Z", + "state": "" + } +] \ No newline at end of file diff --git a/testdata/entities/hosts/list_ds_networks_all.json b/testdata/entities/hosts/list_ds_networks_all.json new file mode 100644 index 0000000..8dab390 --- /dev/null +++ b/testdata/entities/hosts/list_ds_networks_all.json @@ -0,0 +1,28 @@ +[ + { + "id": "testNetId", + "title": "Some Net", + "status": "active", + "cidr": "100.0.8.0/29", + "family": "ipv4", + "interface_type": "public", + "distribution_method": "gateway", + "additional": false, + "created_at": "2025-01-01T12:00:00Z", + "updated_at": "2025-01-01T12:00:00Z", + "state": "" + }, + { + "id": "testNetId2", + "title": "Another Net", + "status": "active", + "cidr": "100.0.8.0/29", + "family": "ipv4", + "interface_type": "public", + "distribution_method": "gateway", + "additional": false, + "created_at": "2025-01-01T12:00:00Z", + "updated_at": "2025-01-01T12:00:00Z", + "state": "" + } +] \ No newline at end of file diff --git a/testdata/entities/hosts/list_ds_networks_pageview.txt b/testdata/entities/hosts/list_ds_networks_pageview.txt new file mode 100644 index 0000000..fa89faa --- /dev/null +++ b/testdata/entities/hosts/list_ds_networks_pageview.txt @@ -0,0 +1,21 @@ +ID: testNetId +Title: Some Net +Status: active +CIDR: 100.0.8.0/29 +Family: ipv4 +InterfaceType: public +DistributionMethod: gateway +Additional: false +Updated: 2025-01-01T12:00:00Z +Created: 2025-01-01T12:00:00Z +--- +ID: testNetId2 +Title: Another Net +Status: active +CIDR: 100.0.8.0/29 +Family: ipv4 +InterfaceType: public +DistributionMethod: gateway +Additional: false +Updated: 2025-01-01T12:00:00Z +Created: 2025-01-01T12:00:00Z diff --git a/testdata/entities/hosts/list_ds_networks_template.txt b/testdata/entities/hosts/list_ds_networks_template.txt new file mode 100644 index 0000000..8f58214 --- /dev/null +++ b/testdata/entities/hosts/list_ds_networks_template.txt @@ -0,0 +1,2 @@ +Network: testNetId Title: Some Net +Network: testNetId2 Title: Another Net From 0b1e412dc802432acad8c89f1e804474b6c5ab6f Mon Sep 17 00:00:00 2001 From: Oleg Isakov Date: Fri, 8 Aug 2025 14:48:12 +0300 Subject: [PATCH 5/5] add list options for networks --- cmd/base/list_options.go | 56 ++++++++++++++++++++++++++++++++++ cmd/entities/hosts/networks.go | 11 +++++-- 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/cmd/base/list_options.go b/cmd/base/list_options.go index f3fd71e..98839c4 100644 --- a/cmd/base/list_options.go +++ b/cmd/base/list_options.go @@ -217,3 +217,59 @@ func (o *EndDateOption[T]) ApplyToCollection(collection serverscom.Collection[T] collection.SetParam("end_date", o.endDate) } } + +type FamilyOption[T any] struct { + family string +} + +func (o *FamilyOption[T]) AddFlags(cmd *cobra.Command) { + cmd.Flags().StringVar(&o.family, "family", "", "Set to 'ipv4' or 'ipv6'") +} + +func (o *FamilyOption[T]) ApplyToCollection(collection serverscom.Collection[T]) { + if o.family != "" { + collection.SetParam("family", o.family) + } +} + +type InterfaceTypeOption[T any] struct { + interfaceType string +} + +func (o *InterfaceTypeOption[T]) AddFlags(cmd *cobra.Command) { + cmd.Flags().StringVar(&o.interfaceType, "interface-type", "", "Type of network interface: public, private, oob") +} + +func (o *InterfaceTypeOption[T]) ApplyToCollection(collection serverscom.Collection[T]) { + if o.interfaceType != "" { + collection.SetParam("interface_type", o.interfaceType) + } +} + +type DistributionMethodOption[T any] struct { + distributionMethod string +} + +func (o *DistributionMethodOption[T]) AddFlags(cmd *cobra.Command) { + cmd.Flags().StringVar(&o.distributionMethod, "distribution-method", "", "Distribution method: route or gateway") +} + +func (o *DistributionMethodOption[T]) ApplyToCollection(collection serverscom.Collection[T]) { + if o.distributionMethod != "" { + collection.SetParam("distribution_method", o.distributionMethod) + } +} + +type AdditionalOption[T any] struct { + additional bool +} + +func (o *AdditionalOption[T]) AddFlags(cmd *cobra.Command) { + cmd.Flags().BoolVar(&o.additional, "additional", false, "Filter additional networks only") +} + +func (o *AdditionalOption[T]) ApplyToCollection(collection serverscom.Collection[T]) { + if o.additional { + collection.SetParam("additional", "true") + } +} diff --git a/cmd/entities/hosts/networks.go b/cmd/entities/hosts/networks.go index 59c0387..bb2650c 100644 --- a/cmd/entities/hosts/networks.go +++ b/cmd/entities/hosts/networks.go @@ -18,9 +18,16 @@ func newListDSNetworksCmd(cmdContext *base.CmdContext) *cobra.Command { return scClient.Hosts.DedicatedServerNetworks(id) } - opts := &base.BaseListOptions[serverscom.Network]{} + opts := base.NewListOptions( + &base.BaseListOptions[serverscom.Network]{}, + &base.SearchPatternOption[serverscom.Network]{}, + &base.FamilyOption[serverscom.Network]{}, + &base.InterfaceTypeOption[serverscom.Network]{}, + &base.DistributionMethodOption[serverscom.Network]{}, + &base.AdditionalOption[serverscom.Network]{}, + ) - return base.NewListCmd("list-networks ", "Dedicated server networks", factory, cmdContext, opts) + return base.NewListCmd("list-networks ", "Dedicated server networks", factory, cmdContext, opts...) } func newGetDSNetworkCmd(cmdContext *base.CmdContext) *cobra.Command {