diff --git a/cmd/get/get.go b/cmd/get/get.go index c824635..77a3163 100644 --- a/cmd/get/get.go +++ b/cmd/get/get.go @@ -4,6 +4,7 @@ import ( "fmt" "os" + "github.com/kloudkit/ws-cli/internals/net" "github.com/spf13/cobra" ) @@ -30,12 +31,12 @@ var settingsCmd = &cobra.Command{ Use: "settings", Short: "Get the VSCode settings", Run: func(cmd *cobra.Command, args []string) { - useWorkspace, _ := cmd.Flags().GetBool("workspace") + useWorkspace, _ := cmd.Flags().GetBool("workspace") - if useWorkspace { - fmt.Fprintln(cmd.OutOrStdout(), "/workspace/.vscode/settings.json") - return - } + if useWorkspace { + fmt.Fprintln(cmd.OutOrStdout(), "/workspace/.vscode/settings.json") + return + } home, exists := os.LookupEnv("HOME") @@ -47,8 +48,34 @@ var settingsCmd = &cobra.Command{ }, } +var ipCmd = &cobra.Command{ + Use: "ip", + Short: "Get the internal or node IP addresses", + RunE: func(cmd *cobra.Command, args []string) error { + var ( + ip string + err error + ) + + useNode, _ := cmd.Flags().GetBool("node") + + if useNode { + ip, err = net.GetNodeIP() + } else { + ip, err = net.GetInternalIP() + } + + if err == nil { + fmt.Fprintln(cmd.OutOrStdout(), ip) + } + + return err + }, +} + func init() { - settingsCmd.Flags().Bool("workspace", false, "Get the workspace settings") + ipCmd.Flags().Bool("node", false, "Get external node IP address") + settingsCmd.Flags().Bool("workspace", false, "Get the workspace settings") - GetCmd.AddCommand(homeCmd, settingsCmd) + GetCmd.AddCommand(homeCmd, ipCmd, settingsCmd) } diff --git a/go.mod b/go.mod index 98dbe99..713c5c0 100644 --- a/go.mod +++ b/go.mod @@ -3,22 +3,27 @@ module github.com/kloudkit/ws-cli go 1.21.6 require ( - github.com/apenella/go-ansible/v2 v2.0.0-rc.2 + github.com/apenella/go-ansible/v2 v2.0.0-rc.3 github.com/spf13/cobra v1.8.0 gotest.tools/v3 v3.5.1 ) require ( - github.com/apenella/go-common-utils/data v0.0.0-20220913191136-86daaa87e7df // indirect - github.com/apenella/go-common-utils/error v0.0.0-20220913191136-86daaa87e7df // indirect + github.com/kr/pretty v0.3.1 // indirect + golang.org/x/crypto v0.22.0 // indirect +) + +require ( + github.com/apenella/go-common-utils/data v0.0.0-20221227202648-5452d804e940 // indirect + github.com/apenella/go-common-utils/error v0.0.0-20221227202648-5452d804e940 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/google/go-cmp v0.5.9 // indirect + github.com/google/go-cmp v0.6.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/stretchr/objx v0.4.0 // indirect - github.com/stretchr/testify v1.8.0 // indirect + github.com/stretchr/objx v0.5.2 // indirect + github.com/stretchr/testify v1.9.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 5d11807..de57bdc 100644 --- a/go.sum +++ b/go.sum @@ -1,36 +1,48 @@ -github.com/apenella/go-ansible/v2 v2.0.0-rc.2 h1:wWU9jDFnBf7y6BgD2NgOkrGRjCk4PrFvQSgItc1kbIE= -github.com/apenella/go-ansible/v2 v2.0.0-rc.2/go.mod h1:CW8BknrWkGIEG+BB6/MNXDYajvH2TwyzZEhwMp0rhBk= -github.com/apenella/go-common-utils/data v0.0.0-20220913191136-86daaa87e7df h1:sEikY2P+NZK/7VZUwIsnXIGElhsuFDSxh1bZYwHxdcI= -github.com/apenella/go-common-utils/data v0.0.0-20220913191136-86daaa87e7df/go.mod h1:cLVL6GjUiKG/WyBzX+KD6h/XRV/HnNZIZbMNNiBgQ9o= -github.com/apenella/go-common-utils/error v0.0.0-20220913191136-86daaa87e7df h1:SvlYbjlsSQDS7hbVT1h012/zdgvcwWJ+Yd9XRiiY/8s= -github.com/apenella/go-common-utils/error v0.0.0-20220913191136-86daaa87e7df/go.mod h1:+3dyIlHX350xJIUIffwMLswZXU+N2FwDE05VuKqxYdw= +github.com/apenella/go-ansible/v2 v2.0.0-rc.3 h1:IZLYp9qPmYlDHCBguie67BE9tPmMFsrGrj510cJ1/NY= +github.com/apenella/go-ansible/v2 v2.0.0-rc.3/go.mod h1:CW8BknrWkGIEG+BB6/MNXDYajvH2TwyzZEhwMp0rhBk= +github.com/apenella/go-common-utils/data v0.0.0-20221227202648-5452d804e940 h1:heIU8S8TKSbqebsLywfM4n8pvQtqjDZHU6gVPbzrQHQ= +github.com/apenella/go-common-utils/data v0.0.0-20221227202648-5452d804e940/go.mod h1:cLVL6GjUiKG/WyBzX+KD6h/XRV/HnNZIZbMNNiBgQ9o= +github.com/apenella/go-common-utils/error v0.0.0-20221227202648-5452d804e940 h1:M6LTqQBjGqTf9t0O2i0GunjhlsX4REK8aSS44sGOEv4= +github.com/apenella/go-common-utils/error v0.0.0-20221227202648-5452d804e940/go.mod h1:+3dyIlHX350xJIUIffwMLswZXU+N2FwDE05VuKqxYdw= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 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/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= +github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= +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/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +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/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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/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/sosedoff/ansible-vault-go v0.2.0 h1:XqkBdqbXgTuFQ++NdrZvSdUTNozeb6S3V5x7FVs17vg= +github.com/sosedoff/ansible-vault-go v0.2.0/go.mod h1:wMU54HNJfY0n0KIgbpA9m15NBfaUDlJrAsaZp0FwzkI= github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= 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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +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= +golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= +golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= 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.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= diff --git a/internals/.gitkeep b/internals/.gitkeep deleted file mode 100644 index 1d88d1f..0000000 --- a/internals/.gitkeep +++ /dev/null @@ -1,10 +0,0 @@ -# Kloud Workspace - CLI - -> ⚡ CLI tool to charge the workspace batteries - -This repository contains the source code for the `ws-cli` tool. - -## License - -This project is licensed under the -[**MIT License**](https://github.com/kloudkit/ws-cli?tab=MIT-1-ov-file#MIT-1-ov-file) diff --git a/internals/net/ipAddress.go b/internals/net/ipAddress.go new file mode 100644 index 0000000..ff42ef4 --- /dev/null +++ b/internals/net/ipAddress.go @@ -0,0 +1,65 @@ +package net + +import ( + "fmt" + "net" + "os" + "strings" +) + +func hexToIPv4(hex string) (net.IP, error) { + ip := make(net.IP, 4) + + _, err := fmt.Sscanf(hex, "%02x%02x%02x%02x", &ip[3], &ip[2], &ip[1], &ip[0]) + + if err != nil { + return nil, err + } + + return ip, nil +} + +func GetNodeIP() (string, error) { + data, err := os.ReadFile("/proc/net/route") + + if err != nil { + return "", err + } + + for _, line := range strings.Split(string(data), "\n") { + fields := strings.Fields(line) + + if len(fields) >= 3 && fields[1] == "00000000" { + ip, err := hexToIPv4(fields[2]) + + if err != nil { + return "", err + } + + return ip.String(), nil + } + } + + return "", fmt.Errorf("default gateway not found") +} + +func GetInternalIP() (string, error) { + addrs, err := net.InterfaceAddrs() + if err != nil { + return "", err + } + + for _, addr := range addrs { + var ip net.IP + + if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { + ip = ipnet.IP.To4() + + if ip != nil { + return ip.String(), nil + } + } + } + + return "", fmt.Errorf("internal IP not found") +}