feat: #1, #2, #3 #5

Merged
evanchen merged 4 commits from dev into master 2021-10-16 14:50:47 +00:00
4 changed files with 76 additions and 26 deletions

View File

@ -1,3 +1,5 @@
SHELL := /bin/bash
VERSION=$(shell git describe --tags) VERSION=$(shell git describe --tags)
BUILD=$(shell git rev-parse --short HEAD) BUILD=$(shell git rev-parse --short HEAD)
PROJ := $(shell basename "$(PWD)") PROJ := $(shell basename "$(PWD)")
@ -25,13 +27,13 @@ build-unix:
$(shell export GOOS=$(GOOS); export GOARCH=$(GOARCH); go build ${LDFLAGS} -o dist/$(PROJ)_$(VERSION)_$(GOOS)_$(GOARCH)/$(PROJ)))) $(shell export GOOS=$(GOOS); export GOARCH=$(GOARCH); go build ${LDFLAGS} -o dist/$(PROJ)_$(VERSION)_$(GOOS)_$(GOARCH)/$(PROJ))))
build-win: build-win:
$(shell export GOOS=windows; export GOARCH=arm64; go build ${LDFLAGS} -o dist/$(PROJ)_$(VERSION)_windows_arm64/$(PROJ).exe) $(shell export GOOS=windows; export GOARCH=amd64; go build ${LDFLAGS} -o dist/$(PROJ)_$(VERSION)_windows_amd64/$(PROJ).exe)
build-mac-m1: build-mac-m1:
$(shell export GOOS=darwin; export GOARCH=arm64; go build ${LDFLAGS} -o dist/$(PROJ)_$(VERSION)_darwin_arm64/$(PROJ)) $(shell export GOOS=darwin; export GOARCH=arm64; go build ${LDFLAGS} -o dist/$(PROJ)_$(VERSION)_darwin_arm64/$(PROJ))
build-zip: build-zip:
cd dist; for f in * ;do tar -czf $${f}.tar.gz $${f}; done cd dist; for f in * ;do if ! [[ $$f =~ "gz" ]] ; then tar -czf $${f}.tar.gz $${f}; fi done
binary: build-unix build-win build-mac-m1 binary: build-unix build-win build-mac-m1

View File

@ -19,16 +19,20 @@ Available Commands:
Flags: Flags:
-a, --all show local ip -a, --all show local ip
-c, --cell show cell, must used with --list -c, --cell show cell, must used with --list
--cron run as cron service
-h, --help help for myip -h, --help help for myip
-u, --host string hostname to connect (default "kumoly.io") -u, --host string hostname to connect (default "kumoly.io")
-l, --list show list -l, --list show list
-n, --name string tell the server who you are
--no-pub disable PublicIP --no-pub disable PublicIP
-p, --port string server port to connect (default "5080") -p, --port string server port to connect (default "5080")
--secure use https --secure use https
-s, --spec string hostname to connect (default "0 */5 * * * *")
-t, --title show title, used with --list -t, --title show title, used with --list
-v, --version version for myip -v, --version version for myip
Use "myip [command] --help" for more information about a command. Use "myip [command] --help" for more information about a command.
``` ```
## Docker ## Docker
@ -40,6 +44,12 @@ docker pull hub.kumoly.io/tools/myip:latest
docker run --name myip-server -d -p 5080:5080 --restart=always hub.kumoly.io/tools/myip docker run --name myip-server -d -p 5080:5080 --restart=always hub.kumoly.io/tools/myip
``` ```
Client:
```shell
docker pull hub.kumoly.io/tools/myip:latest
docker run --name myip -d --restart=always hub.kumoly.io/tools/myip myip --cron --spec "@hourly"
```
## Cron ## Cron
@ -52,6 +62,16 @@ Hours | Yes | 0-23 | * / , -
Day of month | Yes | 1-31 | * / , - ? Day of month | Yes | 1-31 | * / , - ?
Month | Yes | 1-12 or JAN-DEC | * / , - Month | Yes | 1-12 or JAN-DEC | * / , -
Day of week | Yes | 0-6 or SUN-SAT | * / , - ? Day of week | Yes | 0-6 or SUN-SAT | * / , - ?
Entry | Description | Equivalent To
----- | ----------- | -------------
@yearly (or @annually) | Run once a year, midnight, Jan. 1st | 0 0 0 1 1 *
@monthly | Run once a month, midnight, first of month | 0 0 0 1 * *
@weekly | Run once a week, midnight between Sat/Sun | 0 0 0 * * 0
@daily (or @midnight) | Run once a day, midnight | 0 0 0 * * *
@hourly | Run once an hour, beginning of hour | 0 0 * * * *
@every <duration>
``` ```
**Duration**: `myip -altc --cron --spec "@every 5m"` **Duration**: `myip -altc --cron --spec "@every 5m"`

View File

@ -8,8 +8,10 @@ import (
"net" "net"
"net/http" "net/http"
"os" "os"
"sort"
"strings" "strings"
"text/tabwriter" "text/tabwriter"
"time"
"github.com/robfig/cron/v3" "github.com/robfig/cron/v3"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -32,6 +34,12 @@ var (
cronSpec string cronSpec string
) )
type Iface struct {
IP string
HardwareAddr string
Name string
}
var ClientCmd = &cobra.Command{ var ClientCmd = &cobra.Command{
Use: "myip", Use: "myip",
Short: "myip is a easy way to get public ip of current system.", Short: "myip is a easy way to get public ip of current system.",
@ -110,8 +118,8 @@ func Scan() error {
if !noPub { if !noPub {
fmt.Fprintf(w, "\t%v\t%v\t\n", "PublicIP", ip) fmt.Fprintf(w, "\t%v\t%v\t\n", "PublicIP", ip)
} }
for k, v := range local { for _, iface := range local {
fmt.Fprintf(w, "\t%v\t%v\t\n", k, v) fmt.Fprintf(w, "\t%v\t%v\t\n", iface.Name, iface.IP)
} }
return w.Flush() return w.Flush()
@ -120,7 +128,7 @@ func Scan() error {
fmt.Printf("%v ", ip) fmt.Printf("%v ", ip)
} }
for _, v := range local { for _, v := range local {
fmt.Printf("%v ", v) fmt.Printf("%v ", v.IP)
} }
fmt.Printf("\n") fmt.Printf("\n")
} }
@ -128,8 +136,8 @@ func Scan() error {
return nil return nil
} }
func GetLocalIP() (map[string]string, error) { func GetLocalIP() ([]Iface, error) {
ret := map[string]string{} ret := []Iface{}
ifaces, err := net.Interfaces() ifaces, err := net.Interfaces()
if err != nil { if err != nil {
log.Println(err) log.Println(err)
@ -161,10 +169,17 @@ func GetLocalIP() (map[string]string, error) {
// continue // continue
// } // }
} }
ret[i.Name] = ip.String() ret = append(ret, Iface{
IP: ip.String(),
Name: i.Name,
HardwareAddr: i.HardwareAddr.String(),
})
break break
} }
} }
sort.Slice(ret, func(i, j int) bool {
return ret[i].Name < ret[j].Name
})
return ret, nil return ret, nil
} }
@ -173,7 +188,11 @@ func GetPublicIP() (string, error) {
if secure { if secure {
protocol = "https://" protocol = "https://"
} }
res, err := http.Get(protocol + host + ":" + port + "?name=" + name) req, _ := http.NewRequest("GET", protocol+host+":"+port+"?name="+name, nil)
client := &http.Client{
Timeout: time.Second * 10,
}
res, err := client.Do(req)
if err != nil { if err != nil {
log.Println(err) log.Println(err)
return "", err return "", err

View File

@ -5,6 +5,7 @@ import (
"log" "log"
"net" "net"
"net/http" "net/http"
"time"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -31,6 +32,27 @@ func init() {
func StartServer() error { func StartServer() error {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
ip := GetIP(r)
fmt.Fprint(w, ip+"\n")
// logging
user := r.URL.Query().Get("name")
if user == "" {
user = r.URL.String()
}
host, _, _ := net.SplitHostPort(r.RemoteAddr)
log.Printf("%s %s %s %s %s\n", time.Now().Format("2006-01-02-15:04:05"), host, ip, user, r.Header.Get("User-Agent"))
})
err := http.ListenAndServe(addr+":"+port, simpleLogger(http.DefaultServeMux))
if err != nil {
log.Println(err)
return err
}
return nil
}
func GetIP(r *http.Request) string {
ip := r.Header.Get("X-Real-Ip") ip := r.Header.Get("X-Real-Ip")
if ip == "" { if ip == "" {
ip = r.Header.Get("X-Forwarded-For") ip = r.Header.Get("X-Forwarded-For")
@ -42,16 +64,7 @@ func StartServer() error {
ip = r.RemoteAddr ip = r.RemoteAddr
} }
} }
r.Header.Add("X-Myip", ip) return ip
fmt.Fprint(w, ip+"\n")
})
err := http.ListenAndServe(addr+":"+port, simpleLogger(http.DefaultServeMux))
if err != nil {
log.Println(err)
return err
}
return nil
} }
func simpleLogger(handler http.Handler) http.Handler { func simpleLogger(handler http.Handler) http.Handler {
@ -63,11 +76,7 @@ func simpleLogger(handler http.Handler) http.Handler {
// fmt.Println(name, value) // fmt.Println(name, value)
// } // }
// } // }
user := r.URL.Query().Get("name") // log.Printf("%s %s %s %s\n", r.RemoteAddr, r.Method, r.URL, r.Header.Get("User-Agent"))
if user == "" {
user = r.URL.String()
}
log.Printf("%s %s %s %s\n", r.RemoteAddr, r.Method, user, r.Header.Get("User-Agent"))
handler.ServeHTTP(w, r) handler.ServeHTTP(w, r)
}) })
} }