cauto 2 éve
commit
e496f63ea5
48 módosított fájl, 1600 hozzáadás és 0 törlés
  1. 1 0
      .gitattributes
  2. 20 0
      .gitignore
  3. 74 0
      Makefile
  4. 9 0
      README.MD
  5. 12 0
      api/v1/hello.go
  6. 5 0
      go.mod
  7. 168 0
      go.sum
  8. 4 0
      hack/config.yaml
  9. 30 0
      internal/cmd/cmd.go
  10. 1 0
      internal/consts/consts.go
  11. 20 0
      internal/controller/hello.go
  12. 0 0
      internal/dao/.gitkeep
  13. 0 0
      internal/logic/.gitkeep
  14. 0 0
      internal/model/.gitkeep
  15. 0 0
      internal/model/do/.gitkeep
  16. 0 0
      internal/model/entity/.gitkeep
  17. 1 0
      internal/packed/packed.go
  18. 0 0
      internal/service/.gitkeep
  19. 107 0
      library/libResponse/response.go
  20. 126 0
      library/libUtils/utils.go
  21. 23 0
      library/liberr/err.go
  22. 126 0
      library/nettools/dns.go
  23. 151 0
      library/nettools/https.go
  24. 1 0
      library/nettools/icmp_other.go
  25. 9 0
      library/nettools/icmp_unix.go
  26. 303 0
      library/nettools/icmpping.go
  27. 52 0
      library/nettools/pingI.go
  28. 34 0
      library/nettools/resolver.go
  29. 88 0
      library/nettools/tcpping.go
  30. 108 0
      library/nettools/tls.go
  31. 13 0
      main.go
  32. 11 0
      manifest/config/config.yaml
  33. 21 0
      manifest/deploy/kustomize/base/deployment.yaml
  34. 8 0
      manifest/deploy/kustomize/base/kustomization.yaml
  35. 12 0
      manifest/deploy/kustomize/base/service.yaml
  36. 14 0
      manifest/deploy/kustomize/overlays/develop/configmap.yaml
  37. 10 0
      manifest/deploy/kustomize/overlays/develop/deployment.yaml
  38. 14 0
      manifest/deploy/kustomize/overlays/develop/kustomization.yaml
  39. 16 0
      manifest/docker/Dockerfile
  40. 8 0
      manifest/docker/docker.sh
  41. 0 0
      resource/i18n/.gitkeep
  42. 0 0
      resource/public/html/.gitkeep
  43. 0 0
      resource/public/plugin/.gitkeep
  44. 0 0
      resource/public/resource/css/.gitkeep
  45. 0 0
      resource/public/resource/image/.gitkeep
  46. 0 0
      resource/public/resource/js/.gitkeep
  47. 0 0
      resource/template/.gitkeep
  48. 0 0
      utility/.gitkeep

+ 1 - 0
.gitattributes

@@ -0,0 +1 @@
+* linguist-language=GO

+ 20 - 0
.gitignore

@@ -0,0 +1,20 @@
+.buildpath
+.hgignore.swp
+.project
+.orig
+.swp
+.idea/
+.settings/
+.vscode/
+vendor/
+composer.lock
+gitpush.sh
+pkg/
+bin/
+cbuild
+**/.DS_Store
+.test/
+main
+output/
+manifest/output/
+temp/

+ 74 - 0
Makefile

@@ -0,0 +1,74 @@
+ROOT_DIR    = $(shell pwd)
+NAMESPACE   = "default"
+DEPLOY_NAME = "template-single"
+DOCKER_NAME = "template-single"
+
+# Install/Update to the latest CLI tool.
+.PHONY: cli
+cli:
+	@set -e; \
+	wget -O gf https://github.com/gogf/gf/releases/latest/download/gf_$(shell go env GOOS)_$(shell go env GOARCH) && \
+	chmod +x gf && \
+	./gf install -y && \
+	rm ./gf
+
+
+# Check and install CLI tool.
+.PHONY: cli.install
+cli.install:
+	@set -e; \
+	gf -v > /dev/null 2>&1 || if [[ "$?" -ne "0" ]]; then \
+  		echo "GoFame CLI is not installed, start proceeding auto installation..."; \
+		make cli; \
+	fi;
+
+
+# Generate Go files for DAO/DO/Entity.
+.PHONY: dao
+dao: cli.install
+	@gf gen dao
+
+# Generate Go files for Service.
+.PHONY: service
+service: cli.install
+	@gf gen service
+
+# Build image, deploy image and yaml to current kubectl environment and make port forward to local machine.
+.PHONY: start
+start:
+	@set -e; \
+	make image; \
+	make deploy; \
+	make port;
+
+# Build docker image.
+.PHONY: image
+image: cli.install
+	$(eval _TAG  = $(shell git log -1 --format="%cd.%h" --date=format:"%Y%m%d%H%M%S"))
+ifneq (, $(shell git status --porcelain 2>/dev/null))
+	$(eval _TAG  = $(_TAG).dirty)
+endif
+	$(eval _TAG  = $(if ${TAG},  ${TAG}, $(_TAG)))
+	$(eval _PUSH = $(if ${PUSH}, ${PUSH}, ))
+	@gf docker -p -b "-a amd64 -s linux -p temp" -tn $(DOCKER_NAME):${_TAG};
+
+
+# Build docker image and automatically push to docker repo.
+.PHONY: image.push
+image.push:
+	@make image PUSH=-p;
+
+
+# Deploy image and yaml to current kubectl environment.
+.PHONY: deploy
+deploy:
+	$(eval _TAG = $(if ${TAG},  ${TAG}, develop))
+
+	@set -e; \
+	mkdir -p $(ROOT_DIR)/temp/kustomize;\
+	cd $(ROOT_DIR)/manifest/deploy/kustomize/overlays/${_TAG};\
+	kustomize build > $(ROOT_DIR)/temp/kustomize.yaml;\
+	kubectl   apply -f $(ROOT_DIR)/temp/kustomize.yaml; \
+	kubectl   patch -n $(NAMESPACE) deployment/$(DEPLOY_NAME) -p "{\"spec\":{\"template\":{\"metadata\":{\"labels\":{\"date\":\"$(shell date +%s)\"}}}}}";
+
+

+ 9 - 0
README.MD

@@ -0,0 +1,9 @@
+# GoFrame Template For SingleRepo
+
+Project Makefile Commands: 
+- `make cli`: Install or Update to the latest GoFrame CLI tool.
+- `make dao`: Generate go files for `Entity/DAO/DO` according to the configuration file from `hack` folder.
+- `make service`: Parse `logic` folder to generate interface go files into `service` folder.
+- `make image TAG=xxx`: Run `docker build` to build image according `manifest/docker`.
+- `make image.push TAG=xxx`: Run `docker build` and `docker push` to build and push image according `manifest/docker`.
+- `make deploy TAG=xxx`: Run `kustomize build` to build and deploy deployment to kubernetes server group according `manifest/deploy`.

+ 12 - 0
api/v1/hello.go

@@ -0,0 +1,12 @@
+package v1
+
+import (
+	"github.com/gogf/gf/v2/frame/g"
+)
+
+type HelloReq struct {
+	g.Meta `path:"/hello" tags:"Hello" method:"get" summary:"You first hello api"`
+}
+type HelloRes struct {
+	g.Meta `mime:"text/html" example:"string"`
+}

+ 5 - 0
go.mod

@@ -0,0 +1,5 @@
+module nodeMonitor
+
+go 1.15
+
+require github.com/gogf/gf/v2 v2.1.4

+ 168 - 0
go.sum

@@ -0,0 +1,168 @@
+github.com/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I=
+github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
+github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
+github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
+github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
+github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
+github.com/clbanning/mxj/v2 v2.5.5 h1:oT81vUeEiQQ/DcHbzSytRngP6Ky9O+L+0Bw0zSJag9E=
+github.com/clbanning/mxj/v2 v2.5.5/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s=
+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/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
+github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
+github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
+github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
+github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
+github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI=
+github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
+github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
+github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
+github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
+github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
+github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
+github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
+github.com/gogf/gf/v2 v2.1.4 h1:zebl7kahNnU+0o7hcLx81svcTdp5fYdW9ZnZagXyLt4=
+github.com/gogf/gf/v2 v2.1.4/go.mod h1:thvkyb43RWUu/m05sRm4CbH9r7t7/FrW2M56L9Ystwk=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
+github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
+github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
+github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
+github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
+github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
+github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
+github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
+github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
+github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.4.0/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.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
+github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
+github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
+github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
+github.com/grokify/html-strip-tags-go v0.0.1 h1:0fThFwLbW7P/kOiTBs03FsJSV9RM2M/Q/MOnCQxKMo0=
+github.com/grokify/html-strip-tags-go v0.0.1/go.mod h1:2Su6romC5/1VXOQMaWL2yb618ARB8iVo6/DR99A6d78=
+github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
+github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo=
+github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
+github.com/mattn/go-colorable v0.1.9 h1:sqDoxXbdeALODt0DAeJCVp38ps9ZogZEAXjus69YV3U=
+github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
+github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
+github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
+github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
+github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
+github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
+github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
+github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
+github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
+github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
+github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
+github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
+github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
+github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
+github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
+github.com/onsi/ginkgo/v2 v2.0.0 h1:CcuG/HvWNkkaqCUpJifQY8z7qEMBJya6aLPx6ftGyjQ=
+github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
+github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
+github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
+github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
+github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
+github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs=
+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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
+github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
+go.opentelemetry.io/otel v1.7.0 h1:Z2lA3Tdch0iDcrhJXDIlC94XE+bxok1F9B+4Lz/lGsM=
+go.opentelemetry.io/otel v1.7.0/go.mod h1:5BdUoMIz5WEs0vt0CUEMtSSaTSHBBVwrhnz7+nrD5xk=
+go.opentelemetry.io/otel/sdk v1.7.0 h1:4OmStpcKVOfvDOgCt7UriAPtKolwIhxpnSNI/yK+1B0=
+go.opentelemetry.io/otel/sdk v1.7.0/go.mod h1:uTEOTwaqIVuTGiJN7ii13Ibp75wJmYUDe374q6cZwUU=
+go.opentelemetry.io/otel/trace v1.7.0 h1:O37Iogk1lEkMRXewVtZ1BBTVn5JEp8GrJvP92bJqC6o=
+go.opentelemetry.io/otel/trace v1.7.0/go.mod h1:fzLSB9nqR2eXzxPXb2JW9IKE+ScyXA48yyE4TNvoHqU=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
+golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE=
+golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0=
+golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.8-0.20211105212822-18b340fc7af2 h1:GLw7MR8AfAG2GmGcmVgObFOHXYypgGjnGno25RDwn3Y=
+golang.org/x/text v0.3.8-0.20211105212822-18b340fc7af2/go.mod h1:EFNZuWvGYxIRUEX+K8UmCFwYmZjqcrnq15ZuVldZkZ0=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
+google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
+google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
+google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
+google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
+google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
+google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
+google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
+gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

+ 4 - 0
hack/config.yaml

@@ -0,0 +1,4 @@
+
+# CLI tool, only in development environment.
+# https://goframe.org/pages/viewpage.action?pageId=3673173
+gfcli:

+ 30 - 0
internal/cmd/cmd.go

@@ -0,0 +1,30 @@
+package cmd
+
+import (
+	"context"
+
+	"github.com/gogf/gf/v2/frame/g"
+	"github.com/gogf/gf/v2/net/ghttp"
+	"github.com/gogf/gf/v2/os/gcmd"
+
+	"nodeMonitor/internal/controller"
+)
+
+var (
+	Main = gcmd.Command{
+		Name:  "main",
+		Usage: "main",
+		Brief: "start http server",
+		Func: func(ctx context.Context, parser *gcmd.Parser) (err error) {
+			s := g.Server()
+			s.Group("/", func(group *ghttp.RouterGroup) {
+				group.Middleware(ghttp.MiddlewareHandlerResponse)
+				group.Bind(
+					controller.Hello,
+				)
+			})
+			s.Run()
+			return nil
+		},
+	}
+)

+ 1 - 0
internal/consts/consts.go

@@ -0,0 +1 @@
+package consts

+ 20 - 0
internal/controller/hello.go

@@ -0,0 +1,20 @@
+package controller
+
+import (
+	"context"
+
+	"github.com/gogf/gf/v2/frame/g"
+
+	"nodeMonitor/api/v1"
+)
+
+var (
+	Hello = cHello{}
+)
+
+type cHello struct{}
+
+func (c *cHello) Hello(ctx context.Context, req *v1.HelloReq) (res *v1.HelloRes, err error) {
+	g.RequestFromCtx(ctx).Response.Writeln("Hello World!")
+	return
+}

+ 0 - 0
internal/dao/.gitkeep


+ 0 - 0
internal/logic/.gitkeep


+ 0 - 0
internal/model/.gitkeep


+ 0 - 0
internal/model/do/.gitkeep


+ 0 - 0
internal/model/entity/.gitkeep


+ 1 - 0
internal/packed/packed.go

@@ -0,0 +1 @@
+package packed

+ 0 - 0
internal/service/.gitkeep


+ 107 - 0
library/libResponse/response.go

@@ -0,0 +1,107 @@
+package libResponse
+
+import (
+	"github.com/gogf/gf/v2/frame/g"
+	"github.com/gogf/gf/v2/net/ghttp"
+	"github.com/gogf/gf/v2/os/gview"
+	"github.com/gogf/gf/v2/text/gstr"
+	"github.com/gogf/gf/v2/util/gconv"
+)
+
+const (
+	SuccessCode int = 0
+	ErrorCode   int = -1
+)
+
+type Response struct {
+	// 代码
+	Code int `json:"code" example:"200"`
+	// 数据集
+	Data interface{} `json:"data"`
+	// 消息
+	Msg string `json:"message"`
+}
+
+var response = new(Response)
+
+func JsonExit(r *ghttp.Request, code int, msg string, data ...interface{}) {
+	response.JsonExit(r, code, msg, data...)
+}
+
+func RJson(r *ghttp.Request, code int, msg string, data ...interface{}) {
+	response.RJson(r, code, msg, data...)
+}
+
+func SusJson(isExit bool, r *ghttp.Request, msg string, data ...interface{}) {
+	response.SusJson(isExit, r, msg, data...)
+}
+
+func FailJson(isExit bool, r *ghttp.Request, msg string, data ...interface{}) {
+	response.FailJson(isExit, r, msg, data...)
+}
+
+func WriteTpl(r *ghttp.Request, tpl string, view *gview.View, params ...gview.Params) error {
+	return response.WriteTpl(r, tpl, view, params...)
+}
+
+// 返回JSON数据并退出当前HTTP执行函数。
+func (res *Response) JsonExit(r *ghttp.Request, code int, msg string, data ...interface{}) {
+	res.RJson(r, code, msg, data...)
+	r.ExitAll()
+}
+
+// 标准返回结果数据结构封装。
+// 返回固定数据结构的JSON:
+// code:  状态码(200:成功,302跳转,和http请求状态码一至);
+// msg:  请求结果信息;
+// data: 请求结果,根据不同接口返回结果的数据结构不同;
+func (res *Response) RJson(r *ghttp.Request, code int, msg string, data ...interface{}) {
+	responseData := interface{}(nil)
+	if len(data) > 0 {
+		responseData = data[0]
+	}
+	response = &Response{
+		Code: code,
+		Msg:  msg,
+		Data: responseData,
+	}
+	r.Response.WriteJson(response)
+}
+
+// 成功返回JSON
+func (res *Response) SusJson(isExit bool, r *ghttp.Request, msg string, data ...interface{}) {
+	if isExit {
+		res.JsonExit(r, SuccessCode, msg, data...)
+	}
+	res.RJson(r, SuccessCode, msg, data...)
+}
+
+// 失败返回JSON
+func (res *Response) FailJson(isExit bool, r *ghttp.Request, msg string, data ...interface{}) {
+	if isExit {
+		res.JsonExit(r, ErrorCode, msg, data...)
+	}
+	res.RJson(r, ErrorCode, msg, data...)
+}
+
+// WriteTpl 模板输出
+func (res *Response) WriteTpl(r *ghttp.Request, tpl string, view *gview.View, params ...gview.Params) error {
+	//绑定模板中需要用到的方法
+	view.BindFuncMap(g.Map{
+		// 根据长度i来切割字符串
+		"subStr": func(str interface{}, i int) (s string) {
+			s1 := gconv.String(str)
+			if gstr.LenRune(s1) > i {
+				s = gstr.SubStrRune(s1, 0, i) + "..."
+				return s
+			}
+			return s1
+		},
+	})
+	r.Response.Write(view.Parse(r.GetCtx(), tpl, params...))
+	return nil
+}
+
+func (res *Response) Redirect(r *ghttp.Request, location string, code ...int) {
+	r.Response.RedirectTo(location, code...)
+}

+ 126 - 0
library/libUtils/utils.go

@@ -0,0 +1,126 @@
+/*
+* @desc:工具
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu
+* @Date:   2022/3/4 22:16
+ */
+
+package libUtils
+
+import (
+	"context"
+	"fmt"
+	"github.com/gogf/gf/v2/crypto/gmd5"
+	"github.com/gogf/gf/v2/encoding/gcharset"
+	"github.com/gogf/gf/v2/encoding/gjson"
+	"github.com/gogf/gf/v2/encoding/gurl"
+	"github.com/gogf/gf/v2/frame/g"
+	"github.com/gogf/gf/v2/net/ghttp"
+	"net"
+	"os"
+	"path"
+	"strings"
+)
+
+// EncryptPassword 密码加密
+func EncryptPassword(password, salt string) string {
+	return gmd5.MustEncryptString(gmd5.MustEncryptString(password) + gmd5.MustEncryptString(salt))
+}
+
+// GetDomain 获取当前请求接口域名
+func GetDomain(ctx context.Context) string {
+	r := g.RequestFromCtx(ctx)
+	pathInfo, err := gurl.ParseURL(r.GetUrl(), -1)
+	if err != nil {
+		g.Log().Error(ctx, err)
+		return ""
+	}
+	return fmt.Sprintf("%s://%s:%s/", pathInfo["scheme"], pathInfo["host"], pathInfo["port"])
+}
+
+// GetClientIp 获取客户端IP
+func GetClientIp(ctx context.Context) string {
+	return g.RequestFromCtx(ctx).GetClientIp()
+}
+
+// GetUserAgent 获取user-agent
+func GetUserAgent(ctx context.Context) string {
+	return ghttp.RequestFromCtx(ctx).Header.Get("User-Agent")
+}
+
+// GetLocalIP 服务端ip
+func GetLocalIP() (ip string, err error) {
+	var addrs []net.Addr
+	addrs, err = net.InterfaceAddrs()
+	if err != nil {
+		return
+	}
+	for _, addr := range addrs {
+		ipAddr, ok := addr.(*net.IPNet)
+		if !ok {
+			continue
+		}
+		if ipAddr.IP.IsLoopback() {
+			continue
+		}
+		if !ipAddr.IP.IsGlobalUnicast() {
+			continue
+		}
+		return ipAddr.IP.String(), nil
+	}
+	return
+}
+
+// GetCityByIp 获取ip所属城市
+func GetCityByIp(ip string) string {
+	if ip == "" {
+		return ""
+	}
+	if ip == "[::1]" || ip == "127.0.0.1" {
+		return "内网IP"
+	}
+	url := "http://whois.pconline.com.cn/ipJson.jsp?json=true&ip=" + ip
+	bytes := g.Client().GetBytes(context.TODO(), url)
+	src := string(bytes)
+	srcCharset := "GBK"
+	tmp, _ := gcharset.ToUTF8(srcCharset, src)
+	json, err := gjson.DecodeToJson(tmp)
+	if err != nil {
+		return ""
+	}
+	if json.Get("code").Int() == 0 {
+		city := fmt.Sprintf("%s %s", json.Get("pro").String(), json.Get("city").String())
+		return city
+	} else {
+		return ""
+	}
+}
+
+// 写入文件
+func WriteToFile(fileName string, content string) error {
+	f, err := os.OpenFile(fileName, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644)
+	if err != nil {
+		return err
+	}
+	n, _ := f.Seek(0, os.SEEK_END)
+	_, err = f.WriteAt([]byte(content), n)
+	//defer f.Close()
+	return err
+}
+
+// 文件或文件夹是否存在
+func FileIsExisted(filename string) bool {
+	existed := true
+	if _, err := os.Stat(filename); os.IsNotExist(err) {
+		existed = false
+	}
+	return existed
+}
+
+// 解析路径获取文件名称及后缀
+func ParseFilePath(pathStr string) (fileName string, fileType string) {
+	fileNameWithSuffix := path.Base(pathStr)
+	fileType = path.Ext(fileNameWithSuffix)
+	fileName = strings.TrimSuffix(fileNameWithSuffix, fileType)
+	return
+}

+ 23 - 0
library/liberr/err.go

@@ -0,0 +1,23 @@
+package liberr
+
+import (
+	"context"
+	"github.com/gogf/gf/v2/frame/g"
+)
+
+func ErrIsNil(ctx context.Context, err error, msg ...string) {
+	if !g.IsNil(err) {
+		if len(msg) > 0 {
+			g.Log().Error(ctx, err.Error())
+			panic(msg[0])
+		} else {
+			panic(err.Error())
+		}
+	}
+}
+
+func ValueIsNil(value interface{}, msg string) {
+	if g.IsNil(value) {
+		panic(msg)
+	}
+}

+ 126 - 0
library/nettools/dns.go

@@ -0,0 +1,126 @@
+package nettools
+
+import (
+	"crypto/tls"
+	"errors"
+	"fmt"
+	"github.com/miekg/dns"
+	"golang.org/x/net/context"
+	"net"
+	"strconv"
+	"strings"
+	"time"
+)
+
+type DnsPingResult struct {
+	Time int
+	Err  error
+	IP   net.IP
+}
+
+func (dnsR *DnsPingResult) Result() int {
+	return dnsR.Time
+}
+
+func (dnsR *DnsPingResult) Error() error {
+	return dnsR.Err
+}
+
+func (dnsR *DnsPingResult) String() string {
+	if dnsR.Err != nil {
+		return fmt.Sprintf("%s", dnsR.Err)
+	} else {
+		return fmt.Sprintf("%s: time=%d ms", dnsR.IP.String(), dnsR.Time)
+	}
+}
+
+type DnsPing struct {
+	host    string
+	Port    uint16
+	Timeout time.Duration
+
+	// udp, tcp, tcp-tls,默认 udp
+	Net string
+
+	// A, AAAA, NS, ...,默认 NS
+	Type string
+
+	// 查询域名,默认 .
+	Domain string
+
+	// Net 为 tcp-tls 时,是否跳过证书验证
+	Insecure bool
+
+	ip net.IP
+}
+
+func (dnsC *DnsPing) SetHost(host string) {
+	dnsC.host = host
+	dnsC.ip = net.ParseIP(host)
+}
+
+func (dnsC *DnsPing) Host() string {
+	return dnsC.host
+}
+
+func (dnsC *DnsPing) Ping() IPingResult {
+	return dnsC.PingContext(context.Background())
+}
+
+func (dnsC *DnsPing) PingContext(ctx context.Context) IPingResult {
+	ip := cloneIP(dnsC.ip)
+	if ip == nil {
+		var err error
+		ip, err = LookupFunc(dnsC.host)
+		if err != nil {
+			return &DnsPingResult{0, err, nil}
+		}
+	}
+
+	msg := &dns.Msg{}
+	qtype, ok := dns.StringToType[dnsC.Type]
+	if !ok {
+		return &DnsPingResult{0, errors.New("unknown type"), nil}
+	}
+	if !strings.HasSuffix(dnsC.Domain, ".") {
+		dnsC.Domain += "."
+	}
+	msg.SetQuestion(dnsC.Domain, qtype)
+	msg.MsgHdr.RecursionDesired = true
+
+	client := &dns.Client{}
+	client.Net = dnsC.Net
+	client.Timeout = dnsC.Timeout
+	client.TLSConfig = &tls.Config{
+		ServerName:         dnsC.host,
+		InsecureSkipVerify: dnsC.Insecure,
+	}
+
+	t0 := time.Now()
+	r, _, err := client.ExchangeContext(ctx, msg, net.JoinHostPort(ip.String(), strconv.Itoa(int(dnsC.Port))))
+	if err != nil {
+		return &DnsPingResult{0, err, nil}
+	}
+	if r == nil || r.Response == false || r.Opcode != dns.OpcodeQuery {
+		return &DnsPingResult{0, errors.New("response error"), nil}
+	}
+	return &DnsPingResult{int(time.Now().Sub(t0).Milliseconds()), nil, ip}
+}
+
+func NewDnsPing(host string, timeout time.Duration) *DnsPing {
+	return &DnsPing{
+		host:     host,
+		Port:     53,
+		Timeout:  timeout,
+		Net:      "udp",
+		Type:     "NS",
+		Domain:   ".",
+		Insecure: false,
+		ip:       net.ParseIP(host),
+	}
+}
+
+var (
+	_ IPing       = (*DnsPing)(nil)
+	_ IPingResult = (*DnsPingResult)(nil)
+)

+ 151 - 0
library/nettools/https.go

@@ -0,0 +1,151 @@
+package nettools
+
+import (
+	"crypto/tls"
+	"fmt"
+	"golang.org/x/net/context"
+	"io/ioutil"
+	"net"
+	"net/http"
+	"net/url"
+	"strings"
+	"time"
+)
+
+type HttpPingResult struct {
+	Time   int
+	Proto  string
+	Status int
+	Length int
+	Err    error
+	IP     net.IP
+}
+
+func (httpR *HttpPingResult) Result() int {
+	return httpR.Time
+}
+
+func (httpR *HttpPingResult) Error() error {
+	return httpR.Err
+}
+
+func (httpR *HttpPingResult) String() string {
+	if httpR.Err != nil {
+		return fmt.Sprintf("%s", httpR.Err)
+	} else {
+		return fmt.Sprintf("%s: protocol=%s, status=%d, length=%d, time=%d ms", httpR.IP.String(), httpR.Proto, httpR.Status, httpR.Length, httpR.Time)
+	}
+}
+
+type HttpPing struct {
+	Method  string
+	URL     string
+	Timeout time.Duration
+
+	// 以下参数全部为可选
+	DisableHttp2       bool
+	DisableCompression bool
+	Insecure           bool
+	Referrer           string
+	UserAgent          string
+	IP                 net.IP
+}
+
+func (httpC *HttpPing) Ping() IPingResult {
+	return httpC.PingContext(context.Background())
+}
+
+func (httpC *HttpPing) PingContext(ctx context.Context) IPingResult {
+	u, err := url.Parse(httpC.URL)
+	if err != nil {
+		return httpC.errorResult(err)
+	}
+	host := u.Hostname()
+	ip := cloneIP(httpC.IP)
+	if ip == nil {
+		var err error
+		ip, err = LookupFunc(host)
+		if err != nil {
+			return httpC.errorResult(err)
+		}
+	}
+
+	dialer := &net.Dialer{
+		Timeout:   httpC.Timeout,
+		KeepAlive: -1,
+	}
+
+	dialfunc := func(ctx context.Context, network, address string) (net.Conn, error) {
+		h, p, err := net.SplitHostPort(address)
+		if err != nil {
+			return nil, err
+		}
+		if ip == nil || !strings.EqualFold(h, host) {
+			var err error
+			ip, err = LookupFunc(h)
+			if err != nil {
+				return nil, err
+			}
+		}
+		addr := net.JoinHostPort(ip.String(), p)
+		return dialer.DialContext(ctx, network, addr)
+	}
+
+	trans := http.DefaultTransport.(*http.Transport).Clone()
+	trans.DialContext = dialfunc
+	trans.DisableKeepAlives = true
+	trans.MaxIdleConnsPerHost = -1
+	trans.DisableCompression = httpC.DisableCompression
+	trans.ForceAttemptHTTP2 = !httpC.DisableHttp2
+	trans.TLSClientConfig = &tls.Config{
+		InsecureSkipVerify: httpC.Insecure,
+	}
+
+	req, err := http.NewRequestWithContext(ctx, httpC.Method, httpC.URL, nil)
+	if err != nil {
+		return httpC.errorResult(err)
+	}
+	if httpC.UserAgent == "" {
+		httpC.UserAgent = "httping"
+	}
+	req.Header.Set("User-Agent", httpC.UserAgent)
+	if httpC.Referrer != "" {
+		req.Header.Set("Referer", httpC.Referrer)
+	}
+	client := &http.Client{}
+	client.Transport = trans
+	client.Timeout = httpC.Timeout
+	client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
+		return http.ErrUseLastResponse
+	}
+	t0 := time.Now()
+	resp, err := client.Do(req)
+	if err != nil {
+		return httpC.errorResult(err)
+	}
+	defer resp.Body.Close()
+	body, err := ioutil.ReadAll(resp.Body)
+	if err != nil {
+		return httpC.errorResult(err)
+	}
+	return &HttpPingResult{int(time.Now().Sub(t0).Milliseconds()), resp.Proto, resp.StatusCode, len(body), nil, ip}
+}
+
+func (httpC *HttpPing) errorResult(err error) *HttpPingResult {
+	r := &HttpPingResult{}
+	r.Err = err
+	return r
+}
+
+func NewHttpPing(method, url string, timeout time.Duration) *HttpPing {
+	return &HttpPing{
+		Method:  method,
+		URL:     url,
+		Timeout: timeout,
+	}
+}
+
+var (
+	_ IPing       = (*HttpPing)(nil)
+	_ IPingResult = (*HttpPingResult)(nil)
+)

+ 1 - 0
library/nettools/icmp_other.go

@@ -0,0 +1 @@
+package nettools

+ 9 - 0
library/nettools/icmp_unix.go

@@ -0,0 +1,9 @@
+package nettools
+
+import (
+	"context"
+)
+
+func (icmpC *IcmpPing) ping_rootless(ctx context.Context) IPingResult {
+	return icmpC.rawping("udp")
+}

+ 303 - 0
library/nettools/icmpping.go

@@ -0,0 +1,303 @@
+package nettools
+
+import (
+	"bytes"
+	"errors"
+	"fmt"
+	"golang.org/x/net/context"
+	"golang.org/x/net/icmp"
+	"golang.org/x/net/ipv4"
+	"golang.org/x/net/ipv6"
+	"math/rand"
+	"net"
+	"os"
+	"syscall"
+	"time"
+)
+
+type IcmpPingResult struct {
+	Time int
+	Err  error
+	IP   net.IP
+	TTL  int
+}
+
+func (icmpR *IcmpPingResult) Result() int {
+	return icmpR.Time
+}
+
+func (icmpR *IcmpPingResult) Error() error {
+	return icmpR.Err
+}
+
+func (icmpR *IcmpPingResult) String() string {
+	if icmpR.Err != nil {
+		return fmt.Sprintf("%s", icmpR.Err)
+	} else {
+		return fmt.Sprintf("%s: time=%d ms, TTL=%d", icmpR.IP.String(), icmpR.Time, icmpR.TTL)
+	}
+}
+
+type IcmpPing struct {
+	host    string
+	Timeout time.Duration
+
+	ip         net.IP
+	Privileged bool
+}
+
+func (icmpC *IcmpPing) SetHost(host string) {
+	icmpC.host = host
+	icmpC.ip = net.ParseIP(host)
+}
+
+func (icmpC *IcmpPing) Host() string {
+	return icmpC.host
+}
+
+func NewIcmpPing(host string, timeout time.Duration) *IcmpPing {
+	p := &IcmpPing{
+		Timeout: timeout,
+	}
+	p.SetHost(host)
+	return p
+}
+
+func (icmpC *IcmpPing) Ping() IPingResult {
+	return icmpC.PingContext(context.Background())
+}
+
+func (icmpC *IcmpPing) PingContext(ctx context.Context) IPingResult {
+	pingfunc := icmpC.ping_rootless
+	if icmpC.Privileged {
+		pingfunc = icmpC.ping_root
+	}
+	return pingfunc(ctx)
+}
+
+func (icmpC *IcmpPing) ping_root(ctx context.Context) IPingResult {
+	return icmpC.rawping("ip")
+}
+
+// https://github.com/sparrc/go-ping/blob/master/ping.go
+
+func (icmpC *IcmpPing) rawping(network string) IPingResult {
+	// 解析IP
+	ip, isipv6, err := icmpC.parseip()
+	if err != nil {
+		return icmpC.errorResult(err)
+	}
+
+	// 创建连接
+	conn, err := icmpC.getconn(network, ip, isipv6)
+	if err != nil {
+		return icmpC.errorResult(err)
+	}
+	defer conn.Close()
+	conn.SetDeadline(time.Now().Add(icmpC.Timeout))
+
+	// 发送
+	r := rand.New(rand.NewSource(time.Now().UnixNano()))
+	sendData := make([]byte, 32)
+	r.Read(sendData)
+	id := os.Getpid() & 0xffff
+	sendMsg := icmpC.getmsg(isipv6, id, 0, sendData)
+	sendMsgBytes, err := sendMsg.Marshal(nil)
+	if err != nil {
+		return icmpC.errorResult(err)
+	}
+	var dst net.Addr = &net.IPAddr{IP: ip}
+	if network == "udp" {
+		dst = &net.UDPAddr{IP: ip}
+	}
+	sendAt := time.Now()
+	for {
+		if _, err := conn.WriteTo(sendMsgBytes, dst); err != nil {
+			if neterr, ok := err.(*net.OpError); ok {
+				if neterr.Err == syscall.ENOBUFS {
+					continue
+				}
+			}
+		}
+		break
+	}
+
+	recvBytes := make([]byte, 1500)
+	recvSize := 0
+
+	for {
+		ttl := -1
+		var peer net.Addr
+		if isipv6 {
+			var cm *ipv6.ControlMessage
+			recvSize, cm, peer, err = conn.IPv6PacketConn().ReadFrom(recvBytes)
+			if cm != nil {
+				ttl = cm.HopLimit
+			}
+		} else {
+			var cm *ipv4.ControlMessage
+			recvSize, cm, peer, err = conn.IPv4PacketConn().ReadFrom(recvBytes)
+			if cm != nil {
+				ttl = cm.TTL
+			}
+		}
+		if err != nil {
+			return icmpC.errorResult(err)
+		}
+
+		recvAt := time.Now()
+		recvProto := 1
+		if isipv6 {
+			recvProto = 58
+		}
+		recvMsg, err := icmp.ParseMessage(recvProto, recvBytes[:recvSize])
+		if err != nil {
+			return icmpC.errorResult(err)
+		}
+		recvData, recvID, recvType := icmpC.parserecvmsg(isipv6, recvMsg)
+		// 修正数据长度
+		if len(recvData) > len(sendData) {
+			recvData = recvData[len(recvData)-len(sendData):]
+		}
+		// 收到的数据和发送的数据不一致,继续接收
+		if !bytes.Equal(recvData, sendData) {
+			continue
+		}
+		// 是 echo 回复,但 ID 不一致,继续接收
+		if recvType == 1 && network == "ip" && recvID != id {
+			continue
+		}
+
+		if peer != nil {
+			if _ip := net.ParseIP(peer.String()); _ip != nil {
+				ip = _ip
+			}
+		}
+
+		switch recvType {
+		case 1:
+			// echo
+			return &IcmpPingResult{
+				TTL:  ttl,
+				Time: int(recvAt.Sub(sendAt).Milliseconds()),
+				IP:   ip,
+			}
+		case 2:
+			// destination unreachable
+			return icmpC.errorResult(errors.New(fmt.Sprintf("%s: destination unreachable", ip.String())))
+		case 3:
+			// time exceeded
+			return icmpC.errorResult(errors.New(fmt.Sprintf("%s: time exceeded", ip.String())))
+		}
+	}
+}
+
+func (icmpC *IcmpPing) parseip() (ip net.IP, ipv6 bool, err error) {
+	err = nil
+	ip = cloneIP(icmpC.ip)
+	if ip == nil {
+		ip, err = LookupFunc(icmpC.host)
+		if err != nil {
+			return
+		}
+	}
+	if isIPv4(ip) {
+		ipv6 = false
+	} else if isIPv6(ip) {
+		ipv6 = true
+	} else {
+		err = errors.New("lookup ip failed")
+	}
+	return
+}
+
+func (icmpC *IcmpPing) getconn(network string, ip net.IP, isipv6 bool) (*icmp.PacketConn, error) {
+	ipv4Proto := map[string]string{"ip": "ip4:icmp", "udp": "udp4"}
+	ipv6Proto := map[string]string{"ip": "ip6:ipv6-icmp", "udp": "udp6"}
+	icmpnetwork := ""
+	if isipv6 {
+		icmpnetwork = ipv6Proto[network]
+	} else {
+		icmpnetwork = ipv4Proto[network]
+	}
+	conn, err := icmp.ListenPacket(icmpnetwork, "")
+	if err != nil {
+		return nil, err
+	}
+	if isipv6 {
+		conn.IPv6PacketConn().SetControlMessage(ipv6.FlagHopLimit, true)
+	} else {
+		conn.IPv4PacketConn().SetControlMessage(ipv4.FlagTTL, true)
+	}
+	return conn, nil
+}
+
+func (icmpC *IcmpPing) getmsg(isipv6 bool, id, seq int, data []byte) *icmp.Message {
+	var msgtype icmp.Type = ipv4.ICMPTypeEcho
+	if isipv6 {
+		msgtype = ipv6.ICMPTypeEchoRequest
+	}
+	body := &icmp.Echo{
+		ID:   id,
+		Seq:  seq,
+		Data: data,
+	}
+	msg := &icmp.Message{
+		Type: msgtype,
+		Code: 0,
+		Body: body,
+	}
+	return msg
+}
+
+func (icmpC *IcmpPing) parserecvmsg(isipv6 bool, msg *icmp.Message) (data []byte, id, msgtype int) {
+	id = 0
+	data = nil
+	msgtype = 0
+	if isipv6 {
+		switch msg.Type {
+		case ipv6.ICMPTypeEchoReply:
+			msgtype = 1
+		case ipv6.ICMPTypeDestinationUnreachable:
+			msgtype = 2
+		case ipv6.ICMPTypeTimeExceeded:
+			msgtype = 3
+		}
+	} else {
+		switch msg.Type {
+		case ipv4.ICMPTypeEchoReply:
+			msgtype = 1
+		case ipv4.ICMPTypeDestinationUnreachable:
+			msgtype = 2
+		case ipv4.ICMPTypeTimeExceeded:
+			msgtype = 3
+		}
+	}
+	switch msgtype {
+	case 1:
+		if tempmsg, ok := msg.Body.(*icmp.Echo); ok {
+			data = tempmsg.Data
+			id = tempmsg.ID
+		}
+	case 2:
+		if tempmsg, ok := msg.Body.(*icmp.DstUnreach); ok {
+			data = tempmsg.Data
+		}
+	case 3:
+		if tempmsg, ok := msg.Body.(*icmp.TimeExceeded); ok {
+			data = tempmsg.Data
+		}
+	}
+	return
+}
+
+func (icmpC *IcmpPing) errorResult(err error) IPingResult {
+	r := &IcmpPingResult{}
+	r.Err = err
+	return r
+}
+
+var (
+	_ IPing       = (*IcmpPing)(nil)
+	_ IPingResult = (*IcmpPingResult)(nil)
+)

+ 52 - 0
library/nettools/pingI.go

@@ -0,0 +1,52 @@
+package nettools
+
+import (
+	"crypto/tls"
+	"fmt"
+	"golang.org/x/net/context"
+	"net"
+)
+
+type IPingResult interface {
+	Result() int
+	Error() error
+	fmt.Stringer
+}
+
+type IPing interface {
+	Ping() IPingResult
+	PingContext(context.Context) IPingResult
+}
+
+func tlsVersionToString(ver uint16) string {
+	switch ver {
+	case tls.VersionSSL30:
+		return "SSL 3.0"
+	case tls.VersionTLS10:
+		return "TLS 1.0"
+	case tls.VersionTLS11:
+		return "TLS 1.1"
+	case tls.VersionTLS12:
+		return "TLS 1.2"
+	case tls.VersionTLS13:
+		return "TLS 1.3"
+	default:
+		return "unknown"
+	}
+}
+
+func isIPv4(ip net.IP) bool {
+	return len(ip.To4()) == net.IPv4len
+}
+
+func isIPv6(ip net.IP) bool {
+	return len(ip) == net.IPv6len && !isIPv4(ip)
+}
+func cloneIP(ip net.IP) net.IP {
+	var ip2 net.IP
+	if ip != nil {
+		ip2 = make(net.IP, len(ip))
+		copy(ip2, ip)
+	}
+	return ip2
+}

+ 34 - 0
library/nettools/resolver.go

@@ -0,0 +1,34 @@
+package nettools
+
+import "net"
+
+func lookupIP(host string, ipv4, ipv6 bool) (net.IP, error) {
+	ip, err := net.LookupIP(host)
+	if err != nil {
+		return nil, err
+	}
+	for _, i := range ip {
+		if (ipv4 && isIPv4(i)) || (ipv6 && isIPv6(i)) {
+			return i, nil
+		}
+	}
+	return nil, &net.DNSError{
+		Name:       host,
+		Err:        "not found",
+		IsNotFound: true,
+	}
+}
+
+func LookupIPv4(host string) (net.IP, error) {
+	return lookupIP(host, true, false)
+}
+
+func LookupIPv6(host string) (net.IP, error) {
+	return lookupIP(host, false, true)
+}
+
+func LookupIP(host string) (net.IP, error) {
+	return lookupIP(host, true, true)
+}
+
+var LookupFunc func(string) (net.IP, error) = LookupIP

+ 88 - 0
library/nettools/tcpping.go

@@ -0,0 +1,88 @@
+package nettools
+
+import (
+	"fmt"
+	"golang.org/x/net/context"
+	"net"
+	"strconv"
+	"time"
+)
+
+type TcpPingResult struct {
+	Time int
+	Err  error
+	IP   net.IP
+}
+
+func (tcpR *TcpPingResult) Result() int {
+	return tcpR.Time
+}
+
+func (tcpR *TcpPingResult) Error() error {
+	return tcpR.Err
+}
+
+func (tcpR *TcpPingResult) String() string {
+	if tcpR.Err != nil {
+		return fmt.Sprintf("%s", tcpR.Err)
+	} else {
+		return fmt.Sprintf("%s: time=%d ms", tcpR.IP.String(), tcpR.Time)
+	}
+}
+
+type TcpPing struct {
+	host    string
+	Port    int
+	Timeout time.Duration
+
+	ip net.IP
+}
+
+func (tcpC *TcpPing) SetHost(host string) {
+	tcpC.host = host
+	tcpC.ip = net.ParseIP(host)
+}
+
+func (tcpC *TcpPing) Host() string {
+	return tcpC.host
+}
+
+func (tcpC *TcpPing) Ping() IPingResult {
+	return tcpC.PingContext(context.Background())
+}
+
+func (tcpC *TcpPing) PingContext(ctx context.Context) IPingResult {
+	ip := cloneIP(tcpC.ip)
+	if ip == nil {
+		var err error
+		ip, err = LookupFunc(tcpC.host)
+		if err != nil {
+			return &TcpPingResult{0, err, nil}
+		}
+	}
+	dialer := &net.Dialer{
+		Timeout:   tcpC.Timeout,
+		KeepAlive: -1,
+	}
+	t0 := time.Now()
+	conn, err := dialer.DialContext(ctx, "tcp", net.JoinHostPort(ip.String(), strconv.FormatUint(uint64(tcpC.Port), 10)))
+	if err != nil {
+		return &TcpPingResult{0, err, nil}
+	}
+	defer conn.Close()
+	return &TcpPingResult{int(time.Now().Sub(t0).Milliseconds()), nil, ip}
+}
+
+func NewTcpPing(host string, port int, timeout time.Duration) *TcpPing {
+	return &TcpPing{
+		host:    host,
+		Port:    port,
+		Timeout: timeout,
+		ip:      net.ParseIP(host),
+	}
+}
+
+var (
+	_ IPing       = (*TcpPing)(nil)
+	_ IPingResult = (*TcpPingResult)(nil)
+)

+ 108 - 0
library/nettools/tls.go

@@ -0,0 +1,108 @@
+package nettools
+
+import (
+	"crypto/tls"
+	"fmt"
+	"golang.org/x/net/context"
+	"net"
+	"strconv"
+	"time"
+)
+
+type TlsPingResult struct {
+	ConnectionTime int
+	HandshakeTime  int
+	TLSVersion     uint16
+	Err            error
+	IP             net.IP
+}
+
+func (tlsR *TlsPingResult) Result() int {
+	return tlsR.ConnectionTime + tlsR.HandshakeTime
+}
+
+func (tlsR *TlsPingResult) Error() error {
+	return tlsR.Err
+}
+
+func (tlsR *TlsPingResult) String() string {
+	if tlsR.Err != nil {
+		return fmt.Sprintf("%s", tlsR.Err)
+	} else {
+		return fmt.Sprintf("%s: protocol=%s, connection=%d ms, handshake=%d ms, time=%d ms", tlsR.IP.String(), tlsVersionToString(tlsR.TLSVersion), tlsR.ConnectionTime, tlsR.HandshakeTime, tlsR.Result())
+	}
+}
+
+type TlsPing struct {
+	Host              string
+	Port              uint16
+	ConnectionTimeout time.Duration
+	HandshakeTimeout  time.Duration
+
+	// 以下为可选参数
+	TlsVersion uint16
+	Insecure   bool
+	IP         net.IP
+}
+
+func (tslC *TlsPing) Ping() IPingResult {
+	return tslC.PingContext(context.Background())
+}
+
+func (tslC *TlsPing) PingContext(ctx context.Context) IPingResult {
+	ip := cloneIP(tslC.IP)
+	if ip == nil {
+		var err error
+		ip, err = LookupFunc(tslC.Host)
+		if err != nil {
+			return tslC.errorResult(err)
+		}
+	}
+
+	dialer := &net.Dialer{
+		Timeout:   tslC.ConnectionTimeout,
+		KeepAlive: -1,
+	}
+	t0 := time.Now()
+	conn, err := dialer.DialContext(ctx, "tcp", net.JoinHostPort(ip.String(), strconv.FormatUint(uint64(tslC.Port), 10)))
+	if err != nil {
+		return tslC.errorResult(err)
+	}
+	defer conn.Close()
+	t1 := time.Now()
+	config := &tls.Config{
+		ServerName:         tslC.Host,
+		MinVersion:         tslC.TlsVersion,
+		MaxVersion:         tslC.TlsVersion,
+		InsecureSkipVerify: tslC.Insecure,
+	}
+	client := tls.Client(conn, config)
+	client.SetDeadline(time.Now().Add(tslC.HandshakeTimeout))
+	err = client.Handshake()
+	if err != nil {
+		return tslC.errorResult(err)
+	}
+	defer client.Close()
+	t2 := time.Now()
+	return &TlsPingResult{int(t1.Sub(t0).Milliseconds()), int(t2.Sub(t1).Milliseconds()), client.ConnectionState().Version, nil, ip}
+}
+
+func NewTlsPing(host string, port uint16, ct, ht time.Duration) *TlsPing {
+	return &TlsPing{
+		Host:              host,
+		Port:              port,
+		ConnectionTimeout: ct,
+		HandshakeTimeout:  ht,
+	}
+}
+
+func (tslC *TlsPing) errorResult(err error) *TlsPingResult {
+	r := &TlsPingResult{}
+	r.Err = err
+	return r
+}
+
+var (
+	_ IPing       = (*TlsPing)(nil)
+	_ IPingResult = (*TlsPingResult)(nil)
+)

+ 13 - 0
main.go

@@ -0,0 +1,13 @@
+package main
+
+import (
+	_ "nodeMonitor/internal/packed"
+
+	"github.com/gogf/gf/v2/os/gctx"
+
+	"nodeMonitor/internal/cmd"
+)
+
+func main() {
+	cmd.Main.Run(gctx.New())
+}

+ 11 - 0
manifest/config/config.yaml

@@ -0,0 +1,11 @@
+server:
+  address:     ":8000"
+  openapiPath: "/api.json"
+  swaggerPath: "/swagger"
+
+logger:
+  level : "all"
+  stdout: true
+
+
+

+ 21 - 0
manifest/deploy/kustomize/base/deployment.yaml

@@ -0,0 +1,21 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: template-single
+  labels:
+    app: template-single
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: template-single
+  template:
+    metadata:
+      labels:
+        app: template-single
+    spec:
+      containers:
+        - name : main
+          image: template-single
+          imagePullPolicy: Always
+

+ 8 - 0
manifest/deploy/kustomize/base/kustomization.yaml

@@ -0,0 +1,8 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+resources:
+- deployment.yaml
+- service.yaml
+
+
+

+ 12 - 0
manifest/deploy/kustomize/base/service.yaml

@@ -0,0 +1,12 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: template-single
+spec:
+  ports:
+  - port: 80
+    protocol: TCP
+    targetPort: 8000
+  selector:
+    app: template-single
+

+ 14 - 0
manifest/deploy/kustomize/overlays/develop/configmap.yaml

@@ -0,0 +1,14 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: template-single-configmap
+data:
+  config.yaml: |
+    server:
+      address:     ":8000"
+      openapiPath: "/api.json"
+      swaggerPath: "/swagger"
+
+    logger:
+      level : "all"
+      stdout: true

+ 10 - 0
manifest/deploy/kustomize/overlays/develop/deployment.yaml

@@ -0,0 +1,10 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: template-single
+spec:
+  template:
+    spec:
+      containers:
+        - name : main
+          image: template-single:develop

+ 14 - 0
manifest/deploy/kustomize/overlays/develop/kustomization.yaml

@@ -0,0 +1,14 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+resources:
+- ../../base
+- configmap.yaml
+
+patchesStrategicMerge:
+- deployment.yaml
+
+namespace: default
+
+
+

+ 16 - 0
manifest/docker/Dockerfile

@@ -0,0 +1,16 @@
+FROM loads/alpine:3.8
+
+###############################################################################
+#                                INSTALLATION
+###############################################################################
+
+ENV WORKDIR                 /app
+ADD resource                $WORKDIR/
+ADD ./temp/linux_amd64/main $WORKDIR/main
+RUN chmod +x $WORKDIR/main
+
+###############################################################################
+#                                   START
+###############################################################################
+WORKDIR $WORKDIR
+CMD ./main

+ 8 - 0
manifest/docker/docker.sh

@@ -0,0 +1,8 @@
+#!/bin/bash
+
+# This shell is executed before docker build.
+
+
+
+
+

+ 0 - 0
resource/i18n/.gitkeep


+ 0 - 0
resource/public/html/.gitkeep


+ 0 - 0
resource/public/plugin/.gitkeep


+ 0 - 0
resource/public/resource/css/.gitkeep


+ 0 - 0
resource/public/resource/image/.gitkeep


+ 0 - 0
resource/public/resource/js/.gitkeep


+ 0 - 0
resource/template/.gitkeep


+ 0 - 0
utility/.gitkeep