diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1fbf887 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* linguist-language=GO \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..49938e5 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,62 @@ +name: hjm-certcheck Build Release +on: + push: + tags: + - v* +env: + TZ: Asia/Shanghai + +jobs: + build: + name: Build And Release + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v3 + with: + go-version-file: './go.mod' + - name: install dependencies and set env.BIN_NAME + run: | + go version + make cli + gf version + echo ${{github.ref}} + pwd + repository_array=(${GITHUB_REPOSITORY//\// }) + binname=${repository_array[1]} + echo ${binname} + echo "BIN_NAME=${binname}" >> $GITHUB_ENV + + - name: Build CLI Binary For All Platform + run: | + gf build main.go -n ${{env.BIN_NAME}} -a all -s linux + - name: Move Files Before Release + run: | + cd temp + for OS in *;do for FILE in $OS/*;\ + do if [[ ${OS} =~ 'windows' ]];\ + then mv $FILE ${{env.BIN_NAME}}_${OS}.exe && rm -rf $OS;\ + else mv $FILE ${{env.BIN_NAME}}_$OS && rm -rf $OS;\ + fi;done;done + pwd + ls + + - name: Create Github Release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.ref }} + release_name: ${{env.BIN_NAME}} Release ${{ github.ref }} + draft: false + prerelease: false + + - name: Upload Release Asset + id: upload-release-asset + uses: alexellis/upload-assets@0.2.2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + asset_paths: '["temp/${{env.BIN_NAME}}_*"]' + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a263bbf --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +.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/ +node_modules/ +yarn.lock +docs/.vitepress/dist/ \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f9bdb68 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 李栋 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..8f5ba93 --- /dev/null +++ b/Makefile @@ -0,0 +1,89 @@ +ROOT_DIR = $(shell pwd) +NAMESPACE = "default" +DEPLOY_NAME = "template-single" +DOCKER_NAME = "hjm-certcheck" +DOCKER_PREFIX = "hjmcloud" +# 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}, dev)) + $(eval _PUSH = $(if ${PUSH}, ${PUSH}, )) + @gf docker $(PUSH) -b "-a amd64 -s linux -p temp" -tn $(DOCKER_NAME):${_TAG} -tp $(DOCKER_PREFIX); + + +# 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)\"}}}}}"; + +# Build binary files and publish. +.PHONY: bin.publish +bin.publish: + @set -e; \ + rm -rf $(ROOT_DIR)/temp; \ + gf build -n $(DOCKER_NAME) -a 386,amd64,arm,arm64 -s linux,darwin,windows -p temp;\ + cd $(ROOT_DIR)/temp;\ + git init;\ + git add -A;\ + git commit -m "deploy | $(shell date +'%Y-%m-%d %H:%M:%S')";\ + echo "$(shell date +'%Y-%m-%d %H:%M:%S')|开始到gitee部署";\ + git push -f git@gitee.com:$(DOCKER_PREFIX)/$(DOCKER_NAME).git master:release;\ + echo "$(shell date +'%Y-%m-%d %H:%M:%S')|完成到gitee部署";\ + open https://gitee.com/$(DOCKER_PREFIX)/$(DOCKER_NAME)/pages; + + diff --git a/README.MD b/README.MD new file mode 100644 index 0000000..3e73066 --- /dev/null +++ b/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`. \ No newline at end of file diff --git a/api/v1/hello.go b/api/v1/hello.go new file mode 100644 index 0000000..b4dd233 --- /dev/null +++ b/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"` +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..67c5eaf --- /dev/null +++ b/go.mod @@ -0,0 +1,8 @@ +module hjm-certcheck + +go 1.15 + +require ( + github.com/JetBlink/dingtalk-notify-go-sdk v0.0.0-20191112085213-0dc836cea13e + github.com/gogf/gf/v2 v2.1.2 +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..637feea --- /dev/null +++ b/go.sum @@ -0,0 +1,170 @@ +github.com/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I= +github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/JetBlink/dingtalk-notify-go-sdk v0.0.0-20191112085213-0dc836cea13e h1:nfcG9Bsw0vnLvVVFwV8LtJ0GX5kwBqL5S0NVmPt/Cg0= +github.com/JetBlink/dingtalk-notify-go-sdk v0.0.0-20191112085213-0dc836cea13e/go.mod h1:D/dMbAJKugY2nKASbJ6oNsqe/qGVkKL0As1CLFeh5RU= +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.2 h1:3YHfbdfJl4SyBp+8R85jvQIa8jy/iR2fr7iHPqnxOWY= +github.com/gogf/gf/v2 v2.1.2/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= diff --git a/hack/config.yaml b/hack/config.yaml new file mode 100644 index 0000000..8d29a62 --- /dev/null +++ b/hack/config.yaml @@ -0,0 +1,5 @@ + +# CLI tool, only in development environment. +# https://goframe.org/pages/viewpage.action?pageId=3673173 +gfcli: + diff --git a/internal/cmd/cmd.go b/internal/cmd/cmd.go new file mode 100644 index 0000000..5cbfa66 --- /dev/null +++ b/internal/cmd/cmd.go @@ -0,0 +1,64 @@ +package cmd + +import ( + "context" + "hjm-certcheck/internal/service" + + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gbuild" + "github.com/gogf/gf/v2/os/gcmd" + "github.com/gogf/gf/v2/os/gcron" +) + +var ( + Main = gcmd.Command{ + Name: "main", + Usage: "main", + Brief: "start cert check server", + Func: func(ctx context.Context, parser *gcmd.Parser) (err error) { + buildInfo := gbuild.Info() + g.Log().Info(ctx, "start hjm-certcheck server ...") + g.Log().Info(ctx, "HJM-CERTCHECK,https://gitee.com/hjmcloud/hjm-certcheck") + g.Log().Info(ctx, "version: ", buildInfo.Git) + cronPattern, err := g.Cfg().Get(ctx, "cron.pattern") + if err != nil { + g.Log().Error(ctx, "get config cron.pattern error: ", err) + return + } + // cronPattern 不能为空 + if cronPattern.IsEmpty() { + g.Log().Error(ctx, "config cron.pattern is empty") + return + } + cronRunOnStart, err := g.Cfg().Get(ctx, "cron.runOnStart") + if err != nil { + g.Log().Error(ctx, "get config cron.runOnStart error: ", err) + return + } + if cronRunOnStart.Bool() { + g.Log().Info(ctx, "cron.runOnStart is true, run cron job on start") + err = service.Checkbyconfig(ctx) + if err != nil { + g.Log().Error(ctx, "run cron job on start error: ", err) + } + } + g.Log().Info(ctx, "cron.pattern: ", cronPattern.String()) + // 增加定时任务 certCheck + g.Log().Info(ctx, "add cron job certCheck ...") + _, err = gcron.Add(ctx, cronPattern.String(), func(ctx context.Context) { + err = service.Checkbyconfig(ctx) + if err != nil { + g.Log().Error(ctx, "add cron job error: ", err) + return + } + }, "certCheck") + g.Log().Info(ctx, "add cron job certCheck success") + + // service.Checkbyconfig(ctx) + + // 防退出 + g.Log().Info(ctx, "hjm-certcheck server is running ...") + select {} + }, + } +) diff --git a/internal/cmd/version.go b/internal/cmd/version.go new file mode 100644 index 0000000..020e221 --- /dev/null +++ b/internal/cmd/version.go @@ -0,0 +1,47 @@ +package cmd + +import ( + "context" + + "github.com/gogf/gf/v2/os/gbuild" + "github.com/gogf/gf/v2/os/gcmd" + "github.com/gogf/gf/v2/util/gutil" +) + +type sVersion struct { + Name string //程序名称 + Homepage string //程序主页 + GoFrame string //goframe version + Golang string //golang version + Git string //git commit id + Time string //build datetime +} + +var ( + Version = gcmd.Command{ + Name: "version", + Usage: "version", + Brief: "show version", + Func: func(ctx context.Context, parser *gcmd.Parser) (err error) { + info := gbuild.Info() + // gutil.Dump(info) + + // 生成sVersion结构体 + res := sVersion{ + Name: "hjm-certcheck", + Homepage: "https://gitee.com/hjmcloud/hjm-certcheck", + GoFrame: info.GoFrame, + Golang: info.Golang, + Git: info.Git, + Time: info.Time, + } + gutil.Dump(res) + return nil + }, + } +) + +// init 初始化模块 +func init() { + Main.AddCommand(&Version) +} diff --git a/internal/consts/consts.go b/internal/consts/consts.go new file mode 100644 index 0000000..d709a2b --- /dev/null +++ b/internal/consts/consts.go @@ -0,0 +1 @@ +package consts diff --git a/internal/controller/hello.go b/internal/controller/hello.go new file mode 100644 index 0000000..fb8fcd4 --- /dev/null +++ b/internal/controller/hello.go @@ -0,0 +1,20 @@ +package controller + +import ( + "context" + + "github.com/gogf/gf/v2/frame/g" + + "hjm-certcheck/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 +} diff --git a/internal/dao/.gitkeep b/internal/dao/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/internal/logic/.gitkeep b/internal/logic/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/internal/model/.gitkeep b/internal/model/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/internal/model/do/.gitkeep b/internal/model/do/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/internal/model/entity/.gitkeep b/internal/model/entity/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/internal/packed/packed.go b/internal/packed/packed.go new file mode 100644 index 0000000..e20ab1e --- /dev/null +++ b/internal/packed/packed.go @@ -0,0 +1 @@ +package packed diff --git a/internal/service/.gitkeep b/internal/service/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/internal/service/certinfo.go b/internal/service/certinfo.go new file mode 100644 index 0000000..63c4417 --- /dev/null +++ b/internal/service/certinfo.go @@ -0,0 +1,72 @@ +package service + +import ( + "context" + "crypto/tls" + "net" + "net/url" + "strings" + "time" + + "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/frame/g" +) + +type sCertInfo struct { + Host string + Port string + Issuer string + CommonName string + NotBefore time.Time + NotAfter time.Time + NotAfterUnix int64 + SANs []string +} + +func GetCertInfo(ctx context.Context, req string) (certInfo *sCertInfo, err error) { + request := strings.ToLower(string(req)) + if !strings.HasPrefix(request, "http") { + request = "https://" + request + } + u, err := url.Parse(request) + if err != nil { + g.Log().Error(ctx, "failed to parse url.") + return nil, err + } + // if u.Scheme is not https, return error + if u.Scheme != "https" { + return nil, gerror.New("scheme is not https") + } + // if u.port is null then use 443 + if u.Port() == "" { + u.Host = u.Host + ":443" + } + address := u.Hostname() + ":" + u.Port() + ipConn, err := net.DialTimeout("tcp", address, 5*time.Second) + if err != nil { + g.Log().Errorf(ctx, "SSL/TLS not enabed on %v\nDial error: %v ", u.Hostname()) + return nil, err + } + defer ipConn.Close() + conn := tls.Client(ipConn, &tls.Config{ + InsecureSkipVerify: true, + ServerName: u.Hostname(), + }) + if err = conn.Handshake(); err != nil { + g.Log().Infof(ctx, "Invalid SSL/TLS for %v\nHandshake error: %v", address, err) + return nil, err + } + defer conn.Close() + cert := conn.ConnectionState().PeerCertificates[0] + certInfo = &sCertInfo{ + Host: u.Hostname(), + Port: u.Port(), + Issuer: cert.Issuer.CommonName, + CommonName: cert.Subject.CommonName, + NotBefore: cert.NotBefore, + NotAfter: cert.NotAfter, + NotAfterUnix: cert.NotAfter.Unix(), + SANs: cert.DNSNames, + } + return certInfo, nil +} diff --git a/internal/service/checkbyconfig.go b/internal/service/checkbyconfig.go new file mode 100644 index 0000000..f564067 --- /dev/null +++ b/internal/service/checkbyconfig.go @@ -0,0 +1,74 @@ +package service + +import ( + "context" + "strconv" + + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" +) + +func Checkbyconfig(ctx context.Context) (err error) { + g.Log().Debug(ctx, "check by config ...") + + // 获取配置文件中的warnLeftDays + cfgWarnLeftDays, err := g.Cfg().Get(ctx, "warnLeftDays") + if err != nil { + g.Log().Error(ctx, "get config warnLeftDays error: ", err) + return + } + // 转换成int + warnLeftDays := cfgWarnLeftDays.Int64() + + // 获取配置文件中的urls + cfgurls, err := g.Cfg().Get(ctx, "urls") + if err != nil { + g.Log().Error(ctx, "get config urls error: ", err) + return + } + // 转换成数组 + urls := cfgurls.Strings() + g.Log().Debug(ctx, "urls: ", urls) + // 定义全部正常标识变量 + allOk := true + // 循环urls + for _, url := range urls { + g.Log().Info(ctx, url, "is checking ...") + certInfo, err := GetCertInfo(ctx, url) + if err != nil { + g.Log().Error(ctx, "failed to get cert info: ", err) + now := gtime.Now().String() + msg := now + "[WARN] " + url + " failed to get cert info: " + err.Error() + DinkTalkSend(ctx, msg) + // return err + allOk = false + continue + } + g.Log().Info(ctx, url, "certInfo: ", certInfo) + // 如果配置文件中的warnLeftDays为0,则不发送 + // if warnLeftDays == 0 { + // g.Log().Info(ctx, "warnLeftDays is 0, skip") + // continue + // } + // 计算证书还有多少天过期(使用unix时间戳) + leftdays := (certInfo.NotAfterUnix - gtime.Now().Unix()) / (60 * 60 * 24) + g.Log().Info(ctx, url, "leftdays: ", leftdays) + // 如果证书还有多少天过期小于配置文件中的warnLeftDays,则发送钉钉消息 + if leftdays < warnLeftDays { + g.Log().Info(ctx, url, "will expire in ", leftdays, " days", ", send dingTalk message") + now := gtime.Now().String() + msg := now + "[WARN] ssl cert in " + url + " will expire in " + strconv.Itoa(int(leftdays)) + " days" + DinkTalkSend(ctx, msg) + allOk = false + } + } + if allOk { + g.Log().Info(ctx, "all ok") + // 获取当前时间 + now := gtime.Now().String() + msg := now + " all ssl cert is ok" + DinkTalkSend(ctx, msg) + } + + return nil +} diff --git a/internal/service/dingtalk.go b/internal/service/dingtalk.go new file mode 100644 index 0000000..19ea61e --- /dev/null +++ b/internal/service/dingtalk.go @@ -0,0 +1,46 @@ +package service + +import ( + "context" + "time" + + dingtalk_robot "github.com/JetBlink/dingtalk-notify-go-sdk" + "github.com/gogf/gf/v2/frame/g" +) + +func DinkTalkSend(ctx context.Context, msg string) (err error) { + // 获取配置文件中的dingTalk.enable + cfgEnable, err := g.Cfg().Get(ctx, "dingTalk.enable") + if err != nil { + g.Log().Error(ctx, "get config dingTalk.enable error: ", err) + return + } + // 转换成bool + enable := cfgEnable.Bool() + // 如果配置文件中的dingTalk.enable为false,则不发送 + if !enable { + g.Log().Info(ctx, "dingTalk.enable is false, skip") + return + } + // 获取配置文件中的dingTalk.accessToken + cfgDingTalkAccessToken, err := g.Cfg().Get(ctx, "dingTalk.accessToken") + if err != nil { + g.Log().Error(ctx, "get config dingTalk.accessToken error: ", err) + return + } + // 获取配置文件中的dingTalk.secret + cfgDingTalkSecret, err := g.Cfg().Get(ctx, "dingTalk.secret") + if err != nil { + g.Log().Error(ctx, "get config dingTalk.secret error: ", err) + return + } + + // 初始化钉钉机器人 + robot := dingtalk_robot.NewRobot(cfgDingTalkAccessToken.String(), cfgDingTalkSecret.String()) + // 发送消息 + robot.SendTextMessage(msg, []string{}, false) + // 休眠5秒,防止触发频率过高 + g.Log().Info(ctx, "sleep 5 seconds") + time.Sleep(5 * time.Second) + return nil +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..7c5521d --- /dev/null +++ b/main.go @@ -0,0 +1,13 @@ +package main + +import ( + _ "hjm-certcheck/internal/packed" + + "github.com/gogf/gf/v2/os/gctx" + + "hjm-certcheck/internal/cmd" +) + +func main() { + cmd.Main.Run(gctx.New()) +} diff --git a/manifest/config/config.yaml b/manifest/config/config.yaml new file mode 100644 index 0000000..aacc110 --- /dev/null +++ b/manifest/config/config.yaml @@ -0,0 +1,31 @@ +# config.yaml for HJMCertcheck service. + +# 日志配置 +logger: + level: "all" + stdout: true + +# 计划任务 + +cron: + pattern: "0 0 8 * * *" # 任务计划 使用CRON语法格式,参考 https://goframe.org/pages/viewpage.action?pageId=30736411 + runOnStart: true # 是否在服务启动时执行一次 ture/false + +##### 以上配置项修改后需要重启生效,以下为动态配置,修改后可直接生效##### + +# 剩余多少天提醒 +warnLeftDays: 7 + +# 钉钉机器人配置 +dingTalk: + enable: false # 是否启用钉钉通知 true/false + accessToken: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # 钉钉机器人accessToken + secret: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # 钉钉机器人secret + +# 要检测的项目列表 +urls: + - "https://www.baidu.com" + - "https://www.163.com" + - "https://www.sohu.com" + - "https://www.lidong.xin" + - "https://gcslaoli.gitee.io" diff --git a/manifest/deploy/kustomize/base/deployment.yaml b/manifest/deploy/kustomize/base/deployment.yaml new file mode 100644 index 0000000..28f1d69 --- /dev/null +++ b/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 + diff --git a/manifest/deploy/kustomize/base/kustomization.yaml b/manifest/deploy/kustomize/base/kustomization.yaml new file mode 100644 index 0000000..302d92d --- /dev/null +++ b/manifest/deploy/kustomize/base/kustomization.yaml @@ -0,0 +1,8 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- deployment.yaml +- service.yaml + + + diff --git a/manifest/deploy/kustomize/base/service.yaml b/manifest/deploy/kustomize/base/service.yaml new file mode 100644 index 0000000..608771c --- /dev/null +++ b/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 + diff --git a/manifest/deploy/kustomize/overlays/develop/configmap.yaml b/manifest/deploy/kustomize/overlays/develop/configmap.yaml new file mode 100644 index 0000000..3b1d0af --- /dev/null +++ b/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 diff --git a/manifest/deploy/kustomize/overlays/develop/deployment.yaml b/manifest/deploy/kustomize/overlays/develop/deployment.yaml new file mode 100644 index 0000000..04e4851 --- /dev/null +++ b/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 \ No newline at end of file diff --git a/manifest/deploy/kustomize/overlays/develop/kustomization.yaml b/manifest/deploy/kustomize/overlays/develop/kustomization.yaml new file mode 100644 index 0000000..4731c47 --- /dev/null +++ b/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 + + + diff --git a/manifest/docker/Dockerfile b/manifest/docker/Dockerfile new file mode 100644 index 0000000..d3abe8f --- /dev/null +++ b/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 diff --git a/manifest/docker/docker.sh b/manifest/docker/docker.sh new file mode 100644 index 0000000..ff393f9 --- /dev/null +++ b/manifest/docker/docker.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# This shell is executed before docker build. + + + + + diff --git a/resource/i18n/.gitkeep b/resource/i18n/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/resource/public/html/.gitkeep b/resource/public/html/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/resource/public/plugin/.gitkeep b/resource/public/plugin/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/resource/public/resource/css/.gitkeep b/resource/public/resource/css/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/resource/public/resource/image/.gitkeep b/resource/public/resource/image/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/resource/public/resource/js/.gitkeep b/resource/public/resource/js/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/resource/template/.gitkeep b/resource/template/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/utility/.gitkeep b/utility/.gitkeep new file mode 100644 index 0000000..e69de29