Create ddns-aliyun
This commit is contained in:
parent
6b8bda2d07
commit
f33d32c228
|
@ -0,0 +1,42 @@
|
|||
name: "ddns-aliyun docker build"
|
||||
|
||||
env:
|
||||
PROJECT: ddns-aliyun
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
ACTIONS_ALLOW_UNSECURE_COMMANDS: true
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Set tag
|
||||
id: tag
|
||||
run: |
|
||||
TAG=$(cat ${{ env.PROJECT }}/Dockerfile | awk 'NR==4 {print $3}')
|
||||
echo "::set-env name=TAG::$TAG"
|
||||
- name: Docker Hub login
|
||||
env:
|
||||
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
|
||||
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
|
||||
run: |
|
||||
echo "${DOCKER_PASSWORD}" | docker login --username ${DOCKER_USERNAME} --password-stdin
|
||||
- name: Set up Docker Buildx
|
||||
id: buildx
|
||||
uses: crazy-max/ghaction-docker-buildx@v1
|
||||
with:
|
||||
buildx-version: latest
|
||||
- name: Build Dockerfile
|
||||
env:
|
||||
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
|
||||
run: |
|
||||
docker buildx build \
|
||||
--platform=linux/amd64,linux/arm64 \
|
||||
--output "type=image,push=true" \
|
||||
--file ${{ env.PROJECT }}/Dockerfile ./${{ env.PROJECT }} \
|
||||
--tag $(echo "${DOCKER_USERNAME}" | tr '[:upper:]' '[:lower:]')/${{ env.PROJECT }}:latest \
|
||||
--tag $(echo "${DOCKER_USERNAME}" | tr '[:upper:]' '[:lower:]')/${{ env.PROJECT }}:${TAG}
|
|
@ -0,0 +1,83 @@
|
|||
name: Build
|
||||
|
||||
"on":
|
||||
"push":
|
||||
"tags":
|
||||
- "v*"
|
||||
"branches":
|
||||
- "*"
|
||||
"pull_request":
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
GO111MODULE: "on"
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
|
||||
- uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.16.4
|
||||
|
||||
- name: Prepare environment
|
||||
run: |-
|
||||
RELEASE_VERSION="${GITHUB_REF##*/}"
|
||||
if [[ "${RELEASE_VERSION}" != v* ]]; then RELEASE_VERSION='dev'; fi
|
||||
echo "RELEASE_VERSION=\"${RELEASE_VERSION}@${GITHUB_SHA:0:10}\"" | tee -a $GITHUB_ENV
|
||||
go mod vendor
|
||||
|
||||
# Test
|
||||
- name: Unit Testing
|
||||
run: go test .
|
||||
|
||||
# Win
|
||||
- run: GOOS=windows GOARCH=386 VERSION=${RELEASE_VERSION} make release
|
||||
- run: GOOS=windows GOARCH=amd64 VERSION=${RELEASE_VERSION} make release
|
||||
|
||||
# MacOS
|
||||
- run: GOOS=darwin GOARCH=amd64 VERSION=${RELEASE_VERSION} make release
|
||||
|
||||
# Linux X86/AMD64
|
||||
- run: GOOS=linux GOARCH=386 VERSION=${RELEASE_VERSION} make release
|
||||
- run: GOOS=linux GOARCH=amd64 VERSION=${RELEASE_VERSION} make release
|
||||
|
||||
# Linux ARM
|
||||
- run: GOOS=linux GOARCH=arm GOARM=6 VERSION=${RELEASE_VERSION} make release
|
||||
- run: GOOS=linux GOARCH=arm64 VERSION=${RELEASE_VERSION} make release
|
||||
|
||||
# Linux MIPS/MIPSLE
|
||||
- run: GOOS=linux GOARCH=mips GOMIPS=softfloat VERSION=${RELEASE_VERSION} make release
|
||||
- run: GOOS=linux GOARCH=mipsle GOMIPS=softfloat VERSION=${RELEASE_VERSION} make release
|
||||
|
||||
# FreeBSD X86
|
||||
- run: GOOS=freebsd GOARCH=386 VERSION=${RELEASE_VERSION} make release
|
||||
- run: GOOS=freebsd GOARCH=amd64 VERSION=${RELEASE_VERSION} make release
|
||||
|
||||
# FreeBSD ARM/ARM64
|
||||
- run: GOOS=freebsd GOARCH=arm GOARM=6 VERSION=${RELEASE_VERSION} make release
|
||||
- run: GOOS=freebsd GOARCH=arm64 VERSION=${RELEASE_VERSION} make release
|
||||
|
||||
- run: ls -l build/aliddns-*
|
||||
|
||||
- name: Create release
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
id: create_release
|
||||
uses: actions/create-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: ${{ github.ref }}
|
||||
release_name: Release ${{ github.ref }}
|
||||
draft: false
|
||||
prerelease: false
|
||||
|
||||
- name: Upload
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
uses: xresloader/upload-to-github-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
file: "build/aliddns-*.tar.gz;build/aliddns-*.zip"
|
||||
tags: true
|
||||
draft: false
|
|
@ -0,0 +1,33 @@
|
|||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
.vscode/
|
||||
release/
|
||||
vendor/
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
*.test
|
||||
*.prof
|
||||
*.upx
|
||||
|
||||
build/
|
||||
debug
|
||||
aliyun-ddns-cli
|
||||
aliddns*
|
|
@ -0,0 +1,32 @@
|
|||
FROM golang:alpine as builder
|
||||
ENV CGO_ENABLED=0 \
|
||||
GO111MODULE=on
|
||||
ENV VERSION 2021-06-11
|
||||
|
||||
RUN apk add --update git curl
|
||||
ADD . $GOPATH/src/github.com/honwen/aliyun-ddns-cli
|
||||
RUN set -ex \
|
||||
&& cd $GOPATH/src/github.com/honwen/aliyun-ddns-cli \
|
||||
&& go build -ldflags "-X main.VersionString=$(curl -sSL https://api.github.com/repos/honwen/aliyun-ddns-cli/commits/master | \
|
||||
sed -n '{/sha/p; /date/p;}' | sed 's/.* \"//g' | cut -c1-10 | tr '[:lower:]' '[:upper:]' | sed 'N;s/\n/@/g' | head -1)" . \
|
||||
&& mv aliyun-ddns-cli $GOPATH/bin/
|
||||
|
||||
|
||||
FROM alpine
|
||||
LABEL MAINTAINER honwen <https://github.com/honwen>
|
||||
|
||||
# /usr/bin/aliyun-ddns-cli
|
||||
COPY --from=builder /go/bin /usr/bin
|
||||
|
||||
ENV AKID=1234567890 \
|
||||
AKSCT=abcdefghijklmn \
|
||||
DOMAIN=ddns.example.win \
|
||||
IPAPI=[IPAPI-GROUP] \
|
||||
REDO=0
|
||||
|
||||
CMD aliyun-ddns-cli \
|
||||
--ipapi ${IPAPI} \
|
||||
${IPV6:+-6} \
|
||||
auto-update \
|
||||
--domain ${DOMAIN} \
|
||||
--redo ${REDO}
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2016-2020 honwen
|
||||
|
||||
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.
|
|
@ -0,0 +1,43 @@
|
|||
NAME=aliddns
|
||||
BASE_BUILDDIR=build
|
||||
BUILDNAME=$(GOOS)-$(GOARCH)$(GOARM)
|
||||
BUILDDIR=$(BASE_BUILDDIR)/$(BUILDNAME)
|
||||
VERSION?=dev
|
||||
|
||||
ifeq ($(GOOS),windows)
|
||||
ext=.exe
|
||||
archiveCmd=zip -9 -r $(NAME)-$(BUILDNAME)-$(VERSION).zip $(BUILDNAME)
|
||||
else
|
||||
ext=
|
||||
archiveCmd=tar czpvf $(NAME)-$(BUILDNAME)-$(VERSION).tar.gz $(BUILDNAME)
|
||||
endif
|
||||
|
||||
.PHONY: default
|
||||
default: build
|
||||
|
||||
build: clean test
|
||||
go build -mod=vendor
|
||||
|
||||
release: check-env-release
|
||||
mkdir -p $(BUILDDIR)
|
||||
cp LICENSE $(BUILDDIR)/
|
||||
cp README.md $(BUILDDIR)/
|
||||
CGO_ENABLED=0 GOOS=$(GOOS) GOARCH=$(GOARCH) go build -mod=vendor -ldflags "-s -w -X main.VersionString=$(VERSION)" -o $(BUILDDIR)/$(NAME)$(ext)
|
||||
cd $(BASE_BUILDDIR) ; $(archiveCmd)
|
||||
|
||||
test:
|
||||
go test -race -v -bench=. ./...
|
||||
|
||||
clean:
|
||||
go clean
|
||||
rm -rf $(BASE_BUILDDIR)
|
||||
|
||||
check-env-release:
|
||||
@ if [ "$(GOOS)" = "" ]; then \
|
||||
echo "Environment variable GOOS not set"; \
|
||||
exit 1; \
|
||||
fi
|
||||
@ if [ "$(GOARCH)" = "" ]; then \
|
||||
echo "Environment variable GOOS not set"; \
|
||||
exit 1; \
|
||||
fi
|
|
@ -0,0 +1,36 @@
|
|||
# ddns-aliyun
|
||||
|
||||
GitHub [stilleshan/dockerfiles](https://github.com/stilleshan/dockerfiles)
|
||||
Docker [stilleshan/ddns-aliyun](https://hub.docker.com/r/stilleshan/ddns-aliyun)
|
||||
> *docker image support for X86 and ARM*
|
||||
|
||||
## 使用
|
||||
### docker 启动
|
||||
```shell
|
||||
docker run -d \
|
||||
-e "AKID=[ALIYUN's AccessKey-ID]" \
|
||||
-e "AKSCT=[ALIYUN's AccessKey-Secret]" \
|
||||
-e "DOMAIN=ddns.yourdomain.com" \
|
||||
-e "REDO=600" \
|
||||
stilleshan/ddns-aliyun
|
||||
```
|
||||
|
||||
- AKID: 填写`AccessKeyID`
|
||||
- AKSCT: 填写`AccessKeySecret`
|
||||
- DOMAIN: 填写`ddns 域名`
|
||||
|
||||
### 示例
|
||||
> 使用二级域名来作为 ddns 域名,例如以下示例使用 ddns.ioiox.com ,需要使用的正式域名添加 CNAME 指向 ddns.ioiox.com 即可.
|
||||
```shell
|
||||
docker run -d \
|
||||
-e "AKID=kzazFUTW0uRIWWtk" \
|
||||
-e "AKSCT=kcbGxOVmc9PUpJWTBWNFNWWnNSbFJW" \
|
||||
-e "DOMAIN=ddns.ioiox.com" \
|
||||
-e "REDO=600" \
|
||||
stilleshan/ddns-aliyun
|
||||
```
|
||||
|
||||
## 参考
|
||||
[群晖NAS网络服务 - docker 部署配置阿里云 DDNS 动态域名解析](https://www.ioiox.com/archives/29.html)
|
||||
更多请参考原始仓库 [honwen/aliyun-ddns-cli](https://github.com/honwen/aliyun-ddns-cli)
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
package dns
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/denverdino/aliyungo/common"
|
||||
)
|
||||
|
||||
type AddDomainArgs struct {
|
||||
DomainName string
|
||||
|
||||
//optional
|
||||
GroupId string
|
||||
}
|
||||
|
||||
type AddDomainResponse struct {
|
||||
common.Response
|
||||
DomainId string
|
||||
DomainName string
|
||||
GroupId string
|
||||
GroupName string
|
||||
PunyCode string
|
||||
DnsServers struct {
|
||||
DnsServer []string
|
||||
}
|
||||
}
|
||||
|
||||
// AddDomain
|
||||
//
|
||||
// You can read doc at https://help.aliyun.com/document_detail/29749.html?spm=5176.doc29805.6.592.6LMqlG
|
||||
func (client *Client) AddDomain(args *AddDomainArgs) (response *AddDomainResponse, err error) {
|
||||
action := "AddDomain"
|
||||
response = &AddDomainResponse{}
|
||||
err = client.Invoke(action, args, response)
|
||||
if err == nil {
|
||||
return response, nil
|
||||
} else {
|
||||
log.Printf("%s error, %v", action, err)
|
||||
return response, err
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package dns
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/denverdino/aliyungo/common"
|
||||
)
|
||||
|
||||
type AddDomainGroupArgs struct {
|
||||
GroupName string
|
||||
}
|
||||
|
||||
type AddDomainGroupResponse struct {
|
||||
common.Response
|
||||
GroupId string
|
||||
GroupName string
|
||||
}
|
||||
|
||||
// AddDomainGroup
|
||||
//
|
||||
// You can read doc at https://help.aliyun.com/document_detail/29762.html?spm=5176.doc29749.6.604.PJtwG1
|
||||
func (client *Client) AddDomainGroup(args *AddDomainGroupArgs) (response *AddDomainGroupResponse, err error) {
|
||||
action := "AddDomainGroup"
|
||||
response = &AddDomainGroupResponse{}
|
||||
err = client.Invoke(action, args, response)
|
||||
if err == nil {
|
||||
return response, nil
|
||||
} else {
|
||||
log.Printf("%s error, %v", action, err)
|
||||
return response, err
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package dns
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAddDomainGroup(t *testing.T) {
|
||||
client := NewTestClientNew()
|
||||
args := AddDomainGroupArgs{
|
||||
GroupName: TestDomainGroupName,
|
||||
}
|
||||
|
||||
response, err := client.AddDomainGroup(&args)
|
||||
if err == nil {
|
||||
t.Logf("AddDomainGroup %s success, %v", TestDomainGroupName, response)
|
||||
|
||||
deleteDomainGroupArgs := DeleteDomainGroupArgs{
|
||||
GroupId: response.GroupId,
|
||||
}
|
||||
client.DeleteDomainGroup(&deleteDomainGroupArgs)
|
||||
|
||||
} else {
|
||||
t.Errorf("Failed to AddDomainGroup, %v", err)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package dns
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/denverdino/aliyungo/common"
|
||||
)
|
||||
|
||||
type AddDomainRecordArgs struct {
|
||||
DomainName string
|
||||
RR string
|
||||
Type string
|
||||
Value string
|
||||
|
||||
//optional
|
||||
Line string
|
||||
}
|
||||
|
||||
type AddDomainRecordResponse struct {
|
||||
common.Response
|
||||
InstanceId string
|
||||
RecordId string
|
||||
}
|
||||
|
||||
// AddDomainRecord
|
||||
//
|
||||
// You can read doc at https://docs.aliyun.com/#/pub/dns/api-reference/record-related&AddDomainRecord
|
||||
func (client *Client) AddDomainRecord(args *AddDomainRecordArgs) (response *AddDomainRecordResponse, err error) {
|
||||
action := "AddDomainRecord"
|
||||
response = &AddDomainRecordResponse{}
|
||||
err = client.Invoke(action, args, response)
|
||||
if err == nil {
|
||||
return response, nil
|
||||
} else {
|
||||
log.Printf("%s error, %v", action, err)
|
||||
return response, err
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package dns
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAddDomainRecord(t *testing.T) {
|
||||
client := NewTestClient()
|
||||
addDomainRecordArgs := AddDomainRecordArgs{
|
||||
DomainName: TestDomainName,
|
||||
RR: "testaddrecord",
|
||||
Type: ARecord,
|
||||
Value: "8.8.8.8",
|
||||
}
|
||||
response, err := client.AddDomainRecord(&addDomainRecordArgs)
|
||||
if err == nil {
|
||||
t.Logf("AddDomainRecord: testaddr for domain: %s Success, %v",
|
||||
TestDomainName, response)
|
||||
|
||||
deleteDomainRecordArgs := DeleteDomainRecordArgs{
|
||||
RecordId: response.RecordId,
|
||||
}
|
||||
client.DeleteDomainRecord(&deleteDomainRecordArgs)
|
||||
} else {
|
||||
t.Errorf("Failed to AddDomainRecord: testaddr for domain: %s", TestDomainName)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package dns
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAddDomain(t *testing.T) {
|
||||
client := NewTestClientNew()
|
||||
args := AddDomainArgs{
|
||||
DomainName: TestDomainName,
|
||||
}
|
||||
|
||||
if res, err := client.AddDomain(&args); err == nil {
|
||||
t.Logf("AddDomain %s success, %v", TestDomainName, res)
|
||||
|
||||
deleteDomainArgs := DeleteDomainArgs{
|
||||
DomainName: TestDomainName,
|
||||
}
|
||||
client.DeleteDomain(&deleteDomainArgs)
|
||||
|
||||
} else {
|
||||
t.Errorf("Failed to AddDomain, %v", err)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package dns
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/denverdino/aliyungo/common"
|
||||
)
|
||||
|
||||
type ChangeDomainGroupArgs struct {
|
||||
DomainName string
|
||||
GroupId string
|
||||
}
|
||||
|
||||
type ChangeDomainGroupResponse struct {
|
||||
common.Response
|
||||
GroupId string
|
||||
GroupName string
|
||||
}
|
||||
|
||||
// ChangeDomainGroup
|
||||
//
|
||||
// You can read doc at https://help.aliyun.com/document_detail/29765.html?spm=5176.doc29764.6.607.WUJQgE
|
||||
func (client *Client) ChangeDomainGroup(args *ChangeDomainGroupArgs) (response *ChangeDomainGroupResponse, err error) {
|
||||
action := "ChangeDomainGroup"
|
||||
response = &ChangeDomainGroupResponse{}
|
||||
err = client.Invoke(action, args, response)
|
||||
if err == nil {
|
||||
return response, nil
|
||||
} else {
|
||||
log.Printf("%s error, %v", action, err)
|
||||
return response, err
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package dns
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestChangeDomainGroup(t *testing.T) {
|
||||
client := NewTestClientNew()
|
||||
|
||||
// create origin group
|
||||
addGroupArgs := AddDomainGroupArgs{
|
||||
GroupName: TestDomainGroupName,
|
||||
}
|
||||
addGroupRes, _ := client.AddDomainGroup(&addGroupArgs)
|
||||
|
||||
// add domain to origin group
|
||||
addDomainArgs := AddDomainArgs{
|
||||
DomainName: TestDomainName,
|
||||
GroupId: addGroupRes.GroupId,
|
||||
}
|
||||
addDomainRes, _ := client.AddDomain(&addDomainArgs)
|
||||
|
||||
// create new group
|
||||
addGroupArgs.GroupName = TestChanegGroupName
|
||||
addGroupRes, _ = client.AddDomainGroup(&addGroupArgs)
|
||||
|
||||
// change to new group
|
||||
changeArgs := ChangeDomainGroupArgs{
|
||||
DomainName: addDomainRes.DomainName,
|
||||
GroupId: addGroupRes.GroupId,
|
||||
}
|
||||
_, err := client.ChangeDomainGroup(&changeArgs)
|
||||
if err == nil {
|
||||
t.Logf("ChangeDomainGroup success")
|
||||
} else {
|
||||
t.Errorf("Failed to ChangeDomainGroup, %v", err)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package dns
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/denverdino/aliyungo/common"
|
||||
)
|
||||
|
||||
type DeleteDomainArgs struct {
|
||||
DomainName string
|
||||
}
|
||||
|
||||
type DeleteDomainResponse struct {
|
||||
common.Response
|
||||
DomainName string
|
||||
}
|
||||
|
||||
// DeleteDomain
|
||||
//
|
||||
// You can read doc at https://help.aliyun.com/document_detail/29750.html?spm=5176.doc29766.6.593.eELaZ7
|
||||
func (client *Client) DeleteDomain(args *DeleteDomainArgs) (response *DeleteDomainResponse, err error) {
|
||||
action := "DeleteDomain"
|
||||
response = &DeleteDomainResponse{}
|
||||
err = client.Invoke(action, args, response)
|
||||
if err == nil {
|
||||
return response, nil
|
||||
} else {
|
||||
log.Printf("%s error, %v", action, err)
|
||||
return response, err
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package dns
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/denverdino/aliyungo/common"
|
||||
)
|
||||
|
||||
type DeleteDomainGroupArgs struct {
|
||||
GroupId string
|
||||
}
|
||||
|
||||
type DeleteDomainGroupResponse struct {
|
||||
common.Response
|
||||
GroupName string
|
||||
}
|
||||
|
||||
// DeleteDomainGroup
|
||||
//
|
||||
// You can read doc at https://help.aliyun.com/document_detail/29764.html?spm=5176.doc29763.6.606.Vm3FyC
|
||||
func (client *Client) DeleteDomainGroup(args *DeleteDomainGroupArgs) (response *DeleteDomainGroupResponse, err error) {
|
||||
action := "DeleteDomainGroup"
|
||||
response = &DeleteDomainGroupResponse{}
|
||||
err = client.Invoke(action, args, response)
|
||||
if err == nil {
|
||||
return response, nil
|
||||
} else {
|
||||
log.Printf("%s error, %v", action, err)
|
||||
return response, err
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package dns
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDeleteDomainGroup(t *testing.T) {
|
||||
client := NewTestClientNew()
|
||||
args := AddDomainGroupArgs{
|
||||
GroupName: TestDomainGroupName,
|
||||
}
|
||||
res, _ := client.AddDomainGroup(&args)
|
||||
|
||||
deleteDomainGroupArgs := DeleteDomainGroupArgs{
|
||||
GroupId: res.GroupId,
|
||||
}
|
||||
response, err := client.DeleteDomainGroup(&deleteDomainGroupArgs)
|
||||
if err == nil {
|
||||
t.Logf("DeleteDomainGroup %s success, %v", TestDomainGroupName, response)
|
||||
} else {
|
||||
t.Errorf("Failed to DeleteDomainGroup, %v", err)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package dns
|
||||
|
||||
import "github.com/denverdino/aliyungo/common"
|
||||
|
||||
type DeleteDomainRecordArgs struct {
|
||||
RecordId string
|
||||
}
|
||||
|
||||
type DeleteDomainRecordResponse struct {
|
||||
common.Response
|
||||
InstanceId string
|
||||
RecordId string
|
||||
}
|
||||
|
||||
// DeleteDomainRecord
|
||||
//
|
||||
// You can read doc at https://docs.aliyun.com/#/pub/dns/api-reference/record-related&DeleteDomainRecord
|
||||
func (client *Client) DeleteDomainRecord(args *DeleteDomainRecordArgs) (response *DeleteDomainRecordResponse, err error) {
|
||||
action := "DeleteDomainRecord"
|
||||
response = &DeleteDomainRecordResponse{}
|
||||
err = client.Invoke(action, args, response)
|
||||
if err == nil {
|
||||
return response, nil
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package dns
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDeleteDomainRecord(t *testing.T) {
|
||||
//prepare
|
||||
client := NewTestClient()
|
||||
addDomainRecordArgs := AddDomainRecordArgs{
|
||||
DomainName: TestDomainName,
|
||||
RR: "testdeleterecordid",
|
||||
Type: ARecord,
|
||||
Value: "8.8.8.8",
|
||||
}
|
||||
|
||||
addResponse, err := client.AddDomainRecord(&addDomainRecordArgs)
|
||||
|
||||
//test delete record
|
||||
deleteDomainRecordArgs := DeleteDomainRecordArgs{
|
||||
RecordId: addResponse.RecordId,
|
||||
}
|
||||
deleteResponse, err := client.DeleteDomainRecord(&deleteDomainRecordArgs)
|
||||
if err == nil {
|
||||
t.Logf("DeleteDomainRecord: %v", deleteResponse)
|
||||
} else {
|
||||
t.Errorf("Failed to DeleteDomainRecord: %s", deleteDomainRecordArgs.RecordId)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package dns
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDeleteDomain(t *testing.T) {
|
||||
client := NewTestClientNew()
|
||||
args := AddDomainArgs{
|
||||
DomainName: TestDomainName,
|
||||
}
|
||||
client.AddDomain(&args)
|
||||
|
||||
deleteDomainArgs := DeleteDomainArgs{
|
||||
DomainName: TestDomainName,
|
||||
}
|
||||
response, err := client.DeleteDomain(&deleteDomainArgs)
|
||||
if err == nil {
|
||||
t.Logf("DeleteDomain %s success, %v", TestDomainName, response)
|
||||
} else {
|
||||
t.Errorf("Failed to DeleteDomain, %v", err)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package dns
|
||||
|
||||
import "github.com/denverdino/aliyungo/common"
|
||||
|
||||
type DeleteSubDomainRecordsArgs struct {
|
||||
DomainName string
|
||||
RR string
|
||||
|
||||
//optional
|
||||
Type string
|
||||
}
|
||||
|
||||
type DeleteSubDomainRecordsResponse struct {
|
||||
common.Response
|
||||
InstanceId string
|
||||
RR string
|
||||
// TotalCount int32
|
||||
}
|
||||
|
||||
// DeleteSubDomainRecords
|
||||
//
|
||||
// You can read doc at https://docs.aliyun.com/#/pub/dns/api-reference/record-related&DeleteSubDomainRecords
|
||||
func (client *Client) DeleteSubDomainRecords(args *DeleteSubDomainRecordsArgs) (response *DeleteSubDomainRecordsResponse, err error) {
|
||||
action := "DeleteSubDomainRecords"
|
||||
response = &DeleteSubDomainRecordsResponse{}
|
||||
err = client.Invoke(action, args, response)
|
||||
if err == nil {
|
||||
return response, nil
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package dns
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDeleteSubDomainRecords(t *testing.T) {
|
||||
//prepare
|
||||
client := NewTestClient()
|
||||
addDomainRecordArgs := AddDomainRecordArgs{
|
||||
DomainName: TestDomainName,
|
||||
RR: "testdeletesubdomainrecords",
|
||||
Type: ARecord,
|
||||
Value: "8.8.8.8",
|
||||
}
|
||||
|
||||
client.AddDomainRecord(&addDomainRecordArgs)
|
||||
|
||||
//test delete subdomain
|
||||
deleteDomainRecordArgs := DeleteSubDomainRecordsArgs{
|
||||
DomainName: TestDomainName,
|
||||
RR: "testdeletesubdomainrecords",
|
||||
}
|
||||
deleteResponse, err := client.DeleteSubDomainRecords(&deleteDomainRecordArgs)
|
||||
if err == nil {
|
||||
t.Logf("DeleteDomainRecord: %v", deleteResponse)
|
||||
} else {
|
||||
t.Errorf("Failed to DeleteSubDomainRecords: %s", deleteDomainRecordArgs.RR)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package dns
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/denverdino/aliyungo/common"
|
||||
)
|
||||
|
||||
type DomainGroupType struct {
|
||||
GroupId string
|
||||
GroupName string
|
||||
}
|
||||
|
||||
type DescribeDomainGroupsArgs struct {
|
||||
//optional
|
||||
common.Pagination
|
||||
KeyWord string
|
||||
}
|
||||
|
||||
type DescribeDomainGroupsResponse struct {
|
||||
response common.Response
|
||||
common.PaginationResult
|
||||
DomainGroups struct {
|
||||
DomainGroup []DomainGroupType
|
||||
}
|
||||
}
|
||||
|
||||
// DescribeDomainGroups
|
||||
//
|
||||
// You can read doc at https://help.aliyun.com/document_detail/29766.html?spm=5176.doc29765.6.608.qcQr2R
|
||||
func (client *Client) DescribeDomainGroups(args *DescribeDomainGroupsArgs) (groups []DomainGroupType, err error) {
|
||||
action := "DescribeDomainGroups"
|
||||
response := &DescribeDomainGroupsResponse{}
|
||||
err = client.Invoke(action, args, response)
|
||||
|
||||
if err != nil {
|
||||
log.Printf("%s error, %v", action, err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return response.DomainGroups.DomainGroup, nil
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package dns
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestDescribeDomainGroups(t *testing.T) {
|
||||
client := NewTestClientNew()
|
||||
describeArgs := DescribeDomainGroupsArgs{}
|
||||
|
||||
_, err := client.DescribeDomainGroups(&describeArgs)
|
||||
if err == nil {
|
||||
t.Logf("DescribeDomainGroups success")
|
||||
} else {
|
||||
t.Errorf("Failed to DescribeDomainGroups: %v", err)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package dns
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/denverdino/aliyungo/common"
|
||||
)
|
||||
|
||||
type DomainType struct {
|
||||
DomainId string
|
||||
DomainName string
|
||||
AliDomain bool
|
||||
GroupId string
|
||||
GroupName string
|
||||
InstanceId string
|
||||
VersionCode string
|
||||
PunyCode string
|
||||
DnsServers struct {
|
||||
DnsServer []string
|
||||
}
|
||||
}
|
||||
|
||||
type DescribeDomainInfoArgs struct {
|
||||
DomainName string
|
||||
}
|
||||
|
||||
type DescribeDomainInfoResponse struct {
|
||||
response common.Response
|
||||
DomainType
|
||||
}
|
||||
|
||||
// DescribeDomainInfo
|
||||
//
|
||||
// You can read doc at https://help.aliyun.com/document_detail/29752.html?spm=5176.doc29751.6.595.VJM3Gy
|
||||
func (client *Client) DescribeDomainInfo(args *DescribeDomainInfoArgs) (domain DomainType, err error) {
|
||||
action := "DescribeDomainInfo"
|
||||
response := &DescribeDomainInfoResponse{}
|
||||
err = client.Invoke(action, args, response)
|
||||
|
||||
if err != nil {
|
||||
log.Printf("%s error, %v", action, err)
|
||||
return DomainType{}, err
|
||||
}
|
||||
|
||||
return response.DomainType, nil
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package dns
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestDescribeDomainInfo(t *testing.T) {
|
||||
client := NewTestClientNew()
|
||||
describeArgs := DescribeDomainInfoArgs{
|
||||
DomainName: TestDomainName,
|
||||
}
|
||||
|
||||
_, err := client.DescribeDomainInfo(&describeArgs)
|
||||
if err == nil {
|
||||
t.Logf("DescribeDomainInfo success")
|
||||
} else {
|
||||
t.Errorf("Failed to DescribeDomainInfo: %v", err)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package dns
|
||||
|
||||
import "github.com/denverdino/aliyungo/common"
|
||||
|
||||
type DescribeDomainRecordInfoArgs struct {
|
||||
RecordId string
|
||||
}
|
||||
|
||||
type DescribeDomainRecordInfoResponse struct {
|
||||
common.Response
|
||||
RecordType
|
||||
}
|
||||
|
||||
// DescribeDomainRecordInfo
|
||||
//
|
||||
// You can read doc at https://docs.aliyun.com/#/pub/dns/api-reference/record-related&DescribeDomainRecordInfo
|
||||
func (client *Client) DescribeDomainRecordInfo(args *DescribeDomainRecordInfoArgs) (response *DescribeDomainRecordInfoResponse, err error) {
|
||||
action := "DescribeDomainRecordInfo"
|
||||
response = &DescribeDomainRecordInfoResponse{}
|
||||
err = client.Invoke(action, args, response)
|
||||
if err == nil {
|
||||
return response, nil
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package dns
|
||||
|
||||
import "github.com/denverdino/aliyungo/common"
|
||||
|
||||
// endpoint change to 'http://alidns.aliyuncs.com' then record ttl and priority change to string
|
||||
type RecordTypeNew struct {
|
||||
DomainName string
|
||||
RecordId string
|
||||
RR string
|
||||
Type string
|
||||
Value string
|
||||
Line string
|
||||
Status string
|
||||
Locked bool
|
||||
}
|
||||
|
||||
type DescribeDomainRecordInfoNewArgs struct {
|
||||
RecordId string
|
||||
}
|
||||
|
||||
type DescribeDomainRecordInfoNewResponse struct {
|
||||
common.Response
|
||||
RecordTypeNew
|
||||
}
|
||||
|
||||
// DescribeDomainRecordInformation
|
||||
//
|
||||
// You can read doc at https://docs.aliyun.com/#/pub/dns/api-reference/record-related&DescribeDomainRecordInfo
|
||||
func (client *Client) DescribeDomainRecordInfoNew(args *DescribeDomainRecordInfoNewArgs) (response *DescribeDomainRecordInfoNewResponse, err error) {
|
||||
action := "DescribeDomainRecordInfo"
|
||||
response = &DescribeDomainRecordInfoNewResponse{}
|
||||
err = client.Invoke(action, args, response)
|
||||
if err == nil {
|
||||
return response, nil
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package dns
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDescribeDomainRecordInfoNew(t *testing.T) {
|
||||
//prepare
|
||||
client := NewTestClientNew()
|
||||
describeArgs := DescribeDomainRecordsNewArgs{
|
||||
DomainName: TestDomainName,
|
||||
}
|
||||
describeArgs.PageSize = 100
|
||||
|
||||
describeResponse, err := client.DescribeDomainRecordsNew(&describeArgs)
|
||||
if err == nil {
|
||||
record := describeResponse.DomainRecords.Record[0]
|
||||
arg := DescribeDomainRecordInfoNewArgs{
|
||||
RecordId: record.RecordId,
|
||||
}
|
||||
response, err := client.DescribeDomainRecordInfoNew(&arg)
|
||||
if err == nil {
|
||||
t.Logf("DescribeDomainRecordInfo success: %v", response)
|
||||
} else {
|
||||
t.Errorf("Failed to DescribeDomainRecordInfo: %s", describeArgs.DomainName)
|
||||
}
|
||||
} else {
|
||||
t.Errorf("Failed to DescribeDomainRecords: %s", describeArgs.DomainName)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package dns
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDescribeDomainRecordInfo(t *testing.T) {
|
||||
//prepare
|
||||
client := NewTestClient()
|
||||
describeArgs := DescribeDomainRecordsArgs{
|
||||
DomainName: TestDomainName,
|
||||
}
|
||||
describeArgs.PageSize = 100
|
||||
|
||||
describeResponse, err := client.DescribeDomainRecords(&describeArgs)
|
||||
if err == nil {
|
||||
record := describeResponse.DomainRecords.Record[0]
|
||||
arg := DescribeDomainRecordInfoArgs{
|
||||
RecordId: record.RecordId,
|
||||
}
|
||||
response, err := client.DescribeDomainRecordInfo(&arg)
|
||||
if err == nil {
|
||||
t.Logf("DescribeDomainRecordInfo success: %v", response)
|
||||
} else {
|
||||
t.Errorf("Failed to DescribeDomainRecordInfo: %s", describeArgs.DomainName)
|
||||
}
|
||||
} else {
|
||||
t.Errorf("Failed to DescribeDomainRecords: %s", describeArgs.DomainName)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package dns
|
||||
|
||||
import "github.com/denverdino/aliyungo/common"
|
||||
|
||||
type DescribeDomainRecordsArgs struct {
|
||||
DomainName string
|
||||
|
||||
//optional
|
||||
common.Pagination
|
||||
RRKeyWord string
|
||||
TypeKeyWord string
|
||||
ValueKeyWord string
|
||||
}
|
||||
|
||||
type DescribeDomainRecordsResponse struct {
|
||||
common.Response
|
||||
common.PaginationResult
|
||||
InstanceId string
|
||||
DomainRecords struct {
|
||||
Record []RecordType
|
||||
}
|
||||
}
|
||||
|
||||
// DescribeDomainRecords
|
||||
//
|
||||
// You can read doc at https://docs.aliyun.com/#/pub/dns/api-reference/record-related&DescribeDomainRecords
|
||||
func (client *Client) DescribeDomainRecords(args *DescribeDomainRecordsArgs) (response *DescribeDomainRecordsResponse, err error) {
|
||||
action := "DescribeDomainRecords"
|
||||
response = &DescribeDomainRecordsResponse{}
|
||||
err = client.Invoke(action, args, response)
|
||||
if err == nil {
|
||||
return response, nil
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package dns
|
||||
|
||||
import "github.com/denverdino/aliyungo/common"
|
||||
|
||||
type DescribeDomainRecordsNewArgs struct {
|
||||
DomainName string
|
||||
|
||||
//optional
|
||||
common.Pagination
|
||||
RRKeyWord string
|
||||
TypeKeyWord string
|
||||
ValueKeyWord string
|
||||
}
|
||||
|
||||
type DescribeDomainRecordsNewResponse struct {
|
||||
common.Response
|
||||
common.PaginationResult
|
||||
InstanceId string
|
||||
DomainRecords struct {
|
||||
Record []RecordTypeNew
|
||||
}
|
||||
}
|
||||
|
||||
// DescribeDomainRecordsNew
|
||||
//
|
||||
// You can read doc at https://docs.aliyun.com/#/pub/dns/api-reference/record-related&DescribeDomainRecords
|
||||
func (client *Client) DescribeDomainRecordsNew(args *DescribeDomainRecordsNewArgs) (response *DescribeDomainRecordsNewResponse, err error) {
|
||||
action := "DescribeDomainRecords"
|
||||
response = &DescribeDomainRecordsNewResponse{}
|
||||
err = client.Invoke(action, args, response)
|
||||
if err == nil {
|
||||
return response, nil
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package dns
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDescribeDomainRecordsNew(t *testing.T) {
|
||||
//prepare
|
||||
client := NewTestClientNew()
|
||||
describeArgs := DescribeDomainRecordsNewArgs{
|
||||
DomainName: TestDomainName,
|
||||
}
|
||||
describeArgs.PageSize = 100
|
||||
|
||||
describeResponse, err := client.DescribeDomainRecordsNew(&describeArgs)
|
||||
if err == nil {
|
||||
t.Logf("DescribeDomainRecords success: TotalCount:%d ", describeResponse.TotalCount)
|
||||
} else {
|
||||
t.Errorf("Failed to DescribeDomainRecords: %s", describeArgs.DomainName)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package dns
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDescribeDomainRecords(t *testing.T) {
|
||||
//prepare
|
||||
client := NewTestClient()
|
||||
describeArgs := DescribeDomainRecordsArgs{
|
||||
DomainName: TestDomainName,
|
||||
}
|
||||
describeArgs.PageSize = 100
|
||||
|
||||
describeResponse, err := client.DescribeDomainRecords(&describeArgs)
|
||||
if err == nil {
|
||||
t.Logf("DescribeDomainRecords success: TotalCount:%d ", describeResponse.TotalCount)
|
||||
} else {
|
||||
t.Errorf("Failed to DescribeDomainRecords: %s", describeArgs.DomainName)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package dns
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/denverdino/aliyungo/common"
|
||||
)
|
||||
|
||||
type DescribeDomainsArgs struct {
|
||||
// optional
|
||||
common.Pagination
|
||||
KeyWord string
|
||||
GroupId string
|
||||
}
|
||||
|
||||
type DescribeDomainsResponse struct {
|
||||
response common.Response
|
||||
common.PaginationResult
|
||||
Domains struct {
|
||||
Domain []DomainType
|
||||
}
|
||||
}
|
||||
|
||||
// DescribeDomains
|
||||
//
|
||||
// You can read doc at https://help.aliyun.com/document_detail/29751.html?spm=5176.doc29750.6.594.dvyRJV
|
||||
func (client *Client) DescribeDomains(args *DescribeDomainsArgs) (domains []DomainType, err error) {
|
||||
action := "DescribeDomains"
|
||||
response := &DescribeDomainsResponse{}
|
||||
err = client.Invoke(action, args, response)
|
||||
|
||||
if err != nil {
|
||||
log.Printf("%s error, %v", action, err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return response.Domains.Domain, err
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package dns
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestDescribeDomains(t *testing.T) {
|
||||
client := NewTestClientNew()
|
||||
describeArgs := DescribeDomainInfoArgs{
|
||||
DomainName: TestDomainName,
|
||||
}
|
||||
|
||||
_, err := client.DescribeDomainInfo(&describeArgs)
|
||||
if err == nil {
|
||||
t.Logf("DescribeDomains success")
|
||||
} else {
|
||||
t.Errorf("Failed to DescribeDomains: %v", err)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package dns
|
||||
|
||||
import "github.com/denverdino/aliyungo/common"
|
||||
|
||||
type DescribeSubDomainRecordsArgs struct {
|
||||
SubDomain string
|
||||
|
||||
//optional
|
||||
PageNumber int32
|
||||
PageSize int32
|
||||
Type string
|
||||
}
|
||||
|
||||
type DescribeSubDomainRecordsResponse struct {
|
||||
common.Response
|
||||
InstanceId string
|
||||
TotalCount int32
|
||||
PageNumber int32
|
||||
PageSize int32
|
||||
DomainRecords struct {
|
||||
Record []RecordType
|
||||
}
|
||||
}
|
||||
|
||||
// DescribeSubDomainRecords
|
||||
//
|
||||
// You can read doc at https://docs.aliyun.com/#/pub/dns/api-reference/record-related&DescribeSubDomainRecords
|
||||
func (client *Client) DescribeSubDomainRecords(args *DescribeSubDomainRecordsArgs) (response *DescribeSubDomainRecordsResponse, err error) {
|
||||
action := "DescribeSubDomainRecords"
|
||||
response = &DescribeSubDomainRecordsResponse{}
|
||||
err = client.Invoke(action, args, response)
|
||||
if err == nil {
|
||||
return response, nil
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package dns
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDescribeSubDomainRecords(t *testing.T) {
|
||||
//prepare
|
||||
client := NewTestClient()
|
||||
describeArgs := DescribeSubDomainRecordsArgs{
|
||||
SubDomain: "go." + TestDomainName,
|
||||
}
|
||||
|
||||
describeResponse, err := client.DescribeSubDomainRecords(&describeArgs)
|
||||
if err == nil {
|
||||
t.Logf("DescribeSubDomainRecords success: %v ", describeResponse)
|
||||
} else {
|
||||
t.Errorf("Failed to DescribeSubDomainRecords: %s", describeArgs.SubDomain)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package dns
|
||||
|
||||
import "github.com/denverdino/aliyungo/common"
|
||||
|
||||
type GetMainDomainNameArgs struct {
|
||||
InputString string
|
||||
}
|
||||
|
||||
type GetMainDomainNameResponse struct {
|
||||
common.Response
|
||||
InstanceId string
|
||||
DomainName string
|
||||
RR string
|
||||
DomainLevel int32
|
||||
}
|
||||
|
||||
// GetMainDomainName
|
||||
//
|
||||
// You can read doc at https://docs.aliyun.com/#/pub/dns/api-reference/domain-related&GetMainDomainName
|
||||
func (client *Client) GetMainDomainName(args *GetMainDomainNameArgs) (response *GetMainDomainNameResponse, err error) {
|
||||
action := "GetMainDomainName"
|
||||
response = &GetMainDomainNameResponse{}
|
||||
err = client.Invoke(action, args, response)
|
||||
if err == nil {
|
||||
return response, nil
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package dns
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGetMainDomainName(t *testing.T) {
|
||||
//prepare
|
||||
client := NewTestClient()
|
||||
args := GetMainDomainNameArgs{
|
||||
InputString: "go." + TestDomainName,
|
||||
}
|
||||
|
||||
resp, err := client.GetMainDomainName(&args)
|
||||
if err == nil {
|
||||
t.Logf("GetMainDomainName success: %v ", resp)
|
||||
} else {
|
||||
t.Errorf("Failed to GetMainDomainName: %s", args.InputString)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package dns
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/denverdino/aliyungo/common"
|
||||
)
|
||||
|
||||
type UpdateDomainGroupArgs struct {
|
||||
GroupId string
|
||||
GroupName string
|
||||
}
|
||||
|
||||
type UpdateDomainGroupResponse struct {
|
||||
common.Response
|
||||
GroupId string
|
||||
GroupName string
|
||||
}
|
||||
|
||||
// UpdateDomainGroup
|
||||
//
|
||||
// You can read doc at https://help.aliyun.com/document_detail/29763.html?spm=5176.doc29762.6.605.iFRKjn
|
||||
func (client *Client) UpdateDomainGroup(args *UpdateDomainGroupArgs) (response *UpdateDomainGroupResponse, err error) {
|
||||
action := "UpdateDomainGroup"
|
||||
response = &UpdateDomainGroupResponse{}
|
||||
err = client.Invoke(action, args, response)
|
||||
if err == nil {
|
||||
return response, nil
|
||||
} else {
|
||||
log.Printf("%s error, %v", action, err)
|
||||
return response, err
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package dns
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestUpdateDomainGroup(t *testing.T) {
|
||||
client := NewTestClientNew()
|
||||
|
||||
addGroupArgs := AddDomainGroupArgs{
|
||||
GroupName: TestDomainGroupName,
|
||||
}
|
||||
addGroupRes, _ := client.AddDomainGroup(&addGroupArgs)
|
||||
|
||||
updateArgs := UpdateDomainGroupArgs{
|
||||
GroupId: addGroupRes.GroupId,
|
||||
GroupName: TestChanegGroupName,
|
||||
}
|
||||
_, err := client.UpdateDomainGroup(&updateArgs)
|
||||
if err == nil {
|
||||
t.Logf("UpdateDomainGroup success")
|
||||
} else {
|
||||
t.Errorf("Failed to UpdateDomainGroup, %v", err)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package dns
|
||||
|
||||
import "github.com/denverdino/aliyungo/common"
|
||||
|
||||
type UpdateDomainRecordArgs struct {
|
||||
RecordId string
|
||||
RR string
|
||||
Type string
|
||||
Value string
|
||||
|
||||
//optional
|
||||
TTL int32
|
||||
Priority int32
|
||||
Line string
|
||||
}
|
||||
|
||||
type UpdateDomainRecordResponse struct {
|
||||
common.Response
|
||||
InstanceId string
|
||||
RecordId string
|
||||
}
|
||||
|
||||
// UpdateDomainRecord
|
||||
//
|
||||
// You can read doc at https://docs.aliyun.com/#/pub/dns/api-reference/record-related&UpdateDomainRecord
|
||||
func (client *Client) UpdateDomainRecord(args *UpdateDomainRecordArgs) (response *UpdateDomainRecordResponse, err error) {
|
||||
action := "UpdateDomainRecord"
|
||||
response = &UpdateDomainRecordResponse{}
|
||||
err = client.Invoke(action, args, response)
|
||||
if err == nil {
|
||||
return response, nil
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package dns
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestUpdateDomainRecord(t *testing.T) {
|
||||
//prepare
|
||||
client := NewTestClient()
|
||||
addDomainRecordArgs := AddDomainRecordArgs{
|
||||
DomainName: TestDomainName,
|
||||
RR: "testupdaterecordid",
|
||||
Value: "8.8.8.8",
|
||||
Type: ARecord,
|
||||
}
|
||||
|
||||
addResponse, err := client.AddDomainRecord(&addDomainRecordArgs)
|
||||
|
||||
// test update record
|
||||
updateArgs := UpdateDomainRecordArgs{
|
||||
RecordId: addResponse.RecordId,
|
||||
RR: addDomainRecordArgs.RR,
|
||||
Value: "4.4.4.4",
|
||||
Type: ARecord,
|
||||
}
|
||||
|
||||
_, err = client.UpdateDomainRecord(&updateArgs)
|
||||
if err == nil {
|
||||
t.Logf("UpdateDomainRecord success: RR:%s Value:%s", updateArgs.RR, updateArgs.Value)
|
||||
} else {
|
||||
t.Errorf("Failed to UpdateDomainRecord: %s", updateArgs.RecordId)
|
||||
}
|
||||
|
||||
//clearup
|
||||
deleteDomainRecordArgs := DeleteDomainRecordArgs{
|
||||
RecordId: addResponse.RecordId,
|
||||
}
|
||||
_, err = client.DeleteDomainRecord(&deleteDomainRecordArgs)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to DeleteDomainRecord: %s", deleteDomainRecordArgs.RecordId)
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package dns
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/denverdino/aliyungo/common"
|
||||
)
|
||||
|
||||
type Client struct {
|
||||
common.Client
|
||||
}
|
||||
|
||||
const (
|
||||
// DNSDefaultEndpoint is the default API endpoint of DNS services
|
||||
DNSDefaultEndpoint = "http://dns.aliyuncs.com"
|
||||
DNSAPIVersion = "2015-01-09"
|
||||
|
||||
DNSDefaultEndpointNew = "http://alidns.aliyuncs.com"
|
||||
)
|
||||
|
||||
// NewClient creates a new instance of DNS client
|
||||
func NewClient(accessKeyId, accessKeySecret string) *Client {
|
||||
endpoint := os.Getenv("DNS_ENDPOINT")
|
||||
if endpoint == "" {
|
||||
endpoint = DNSDefaultEndpoint
|
||||
}
|
||||
return NewClientWithEndpoint(endpoint, accessKeyId, accessKeySecret)
|
||||
}
|
||||
|
||||
// NewClientNew creates a new instance of DNS client, with http://alidns.aliyuncs.com as default endpoint
|
||||
func NewClientNew(accessKeyId, accessKeySecret string) *Client {
|
||||
endpoint := os.Getenv("DNS_ENDPOINT")
|
||||
if endpoint == "" {
|
||||
endpoint = DNSDefaultEndpointNew
|
||||
}
|
||||
return NewClientWithEndpoint(endpoint, accessKeyId, accessKeySecret)
|
||||
}
|
||||
|
||||
// NewCustomClient creates a new instance of ECS client with customized API endpoint
|
||||
func NewCustomClient(accessKeyId, accessKeySecret string, endpoint string) *Client {
|
||||
client := &Client{}
|
||||
client.Init(endpoint, DNSAPIVersion, accessKeyId, accessKeySecret)
|
||||
return client
|
||||
}
|
||||
|
||||
func NewClientWithEndpoint(endpoint string, accessKeyId, accessKeySecret string) *Client {
|
||||
client := &Client{}
|
||||
client.Init(endpoint, DNSAPIVersion, accessKeyId, accessKeySecret)
|
||||
return client
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package dns
|
||||
|
||||
//Modify with your Access Key Id and Access Key Secret
|
||||
const (
|
||||
TestAccessKeyId = "MY_ACCESS_KEY_ID"
|
||||
TestAccessKeySecret = "MY_ACCESS_KEY_SECRET"
|
||||
TestDomainName = "aisafe.win"
|
||||
TestDomainGroupName = "testgroup"
|
||||
TestChanegGroupName = "testchangegroup"
|
||||
)
|
||||
|
||||
var testClient *Client
|
||||
|
||||
func NewTestClient() *Client {
|
||||
if testClient == nil {
|
||||
testClient = NewClient(TestAccessKeyId, TestAccessKeySecret)
|
||||
}
|
||||
return testClient
|
||||
}
|
||||
|
||||
// change DNSDefaultEndpoint to "http://alidns.aliyuncs.com"
|
||||
func NewTestClientNew() *Client {
|
||||
if testClient == nil {
|
||||
testClient = NewClientNew(TestAccessKeyId, TestAccessKeySecret)
|
||||
}
|
||||
return testClient
|
||||
}
|
||||
|
||||
var testDebugClient *Client
|
||||
|
||||
func NewTestClientForDebug() *Client {
|
||||
if testDebugClient == nil {
|
||||
testDebugClient = NewClient(TestAccessKeyId, TestAccessKeySecret)
|
||||
testDebugClient.SetDebug(true)
|
||||
}
|
||||
return testDebugClient
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package dns
|
||||
|
||||
//
|
||||
//you can read doc at https://docs.aliyun.com/#/pub/dns/api-reference/enum-type&record-format
|
||||
const (
|
||||
ARecord = "A"
|
||||
NSRecord = "NS"
|
||||
MXRecord = "MX"
|
||||
TXTRecord = "TXT"
|
||||
CNAMERecord = "CNAME"
|
||||
SRVRecord = "SRV"
|
||||
AAAARecord = "AAAA"
|
||||
RedirectURLRecord = "REDIRECT_URL"
|
||||
ForwordURLRecord = "FORWORD_URL"
|
||||
)
|
||||
|
||||
type RecordType struct {
|
||||
DomainName string
|
||||
RecordId string
|
||||
RR string
|
||||
Type string
|
||||
Value string
|
||||
TTL int32
|
||||
Priority int32
|
||||
Line string
|
||||
Status string
|
||||
Locked bool
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
#!/bin/bash
|
||||
|
||||
name='aliddns'
|
||||
|
||||
MD5='md5sum'
|
||||
if [[ "$(uname)" == 'Darwin' ]]; then
|
||||
MD5='md5'
|
||||
fi
|
||||
|
||||
# UPX=false
|
||||
# if hash upx 2>/dev/null; then
|
||||
# UPX=true
|
||||
# fi
|
||||
|
||||
VERSION=$(curl -sSL https://api.github.com/repos/honwen/aliyun-ddns-cli/commits/master | sed -n '{/sha/p; /date/p;}'| sed 's/.* \"//g' | cut -c1-10 | tr '[:lower:]' '[:upper:]' | sed 'N;s/\n/@/g' | head -1)
|
||||
LDFLAGS="-X main.version=$VERSION -s -w"
|
||||
|
||||
# X86
|
||||
OSES=(windows linux darwin freebsd)
|
||||
# ARCHS=(amd64 386)
|
||||
ARCHS=(amd64)
|
||||
rm -rf ./release
|
||||
mkdir -p ./release
|
||||
for os in ${OSES[@]}; do
|
||||
for arch in ${ARCHS[@]}; do
|
||||
suffix=""
|
||||
if [ "$os" == "windows" ]; then
|
||||
suffix=".exe"
|
||||
fi
|
||||
env CGO_ENABLED=0 GOOS=$os GOARCH=$arch go build -ldflags "$LDFLAGS" -o ./release/${name}_${os}_${arch}${suffix} .
|
||||
# if $UPX; then upx -9 ./release/${name}_${os}_${arch}${suffix} -o ./release/${name}_${os}_${arch}${suffix}_upx; fi
|
||||
tar -C ./release -zcf ./release/${name}_${os}-${arch}-$VERSION.tar.gz ./${name}_${os}_${arch}${suffix}
|
||||
$MD5 ./release/${name}_${os}-${arch}-$VERSION.tar.gz
|
||||
done
|
||||
done
|
||||
|
||||
# ARM64
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags "$LDFLAGS" -o ./release/${name}_arm64 .
|
||||
# ARM
|
||||
ARMS=(5 6 7)
|
||||
for v in ${ARMS[@]}; do
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=$v go build -ldflags "$LDFLAGS" -o ./release/${name}_arm$v .
|
||||
done
|
||||
# if $UPX; then upx -9 ./release/${name}_arm*; fi
|
||||
tar -C ./release -zcf ./release/${name}_arm-$VERSION.tar.gz $(for v in ${ARMS[@]}; do echo -n "./${name}_arm$v ";done)
|
||||
$MD5 ./release/${name}_arm-$VERSION.tar.gz
|
||||
|
||||
# MIPS/hardfloat
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=mipsle go build -ldflags "$LDFLAGS" -o ./release/${name}_mipsle .
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=mips go build -ldflags "$LDFLAGS" -o ./release/${name}_mips .
|
||||
# MIPS/softfloat
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=mipsle GOMIPS=softfloat go build -ldflags "$LDFLAGS" -o ./release/${name}_mipsle_sf .
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=mips GOMIPS=softfloat go build -ldflags "$LDFLAGS" -o ./release/${name}_mips_sf .
|
||||
# if $UPX; then upx -9 ./release/${name}_mips**; fi
|
||||
tar -C ./release -zcf ./release/${name}_mipsle-$VERSION.tar.gz ./${name}_mipsle
|
||||
tar -C ./release -zcf ./release/${name}_mips-$VERSION.tar.gz ./${name}_mips
|
||||
tar -C ./release -zcf ./release/${name}_mipsle-sf-$VERSION.tar.gz ./${name}_mipsle_sf
|
||||
tar -C ./release -zcf ./release/${name}_mips-sf-$VERSION.tar.gz ./${name}_mips_sf
|
||||
$MD5 ./release/${name}_mipsle-$VERSION.tar.gz
|
Binary file not shown.
After Width: | Height: | Size: 208 KiB |
|
@ -0,0 +1,11 @@
|
|||
module github.com/honwen/aliyun-ddns-cli
|
||||
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/denverdino/aliyungo v0.0.0-20210518071019-eb3bbb144d8a
|
||||
github.com/honwen/golibs v0.1.4
|
||||
github.com/honwen/ip2loc v0.1.2
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/urfave/cli v1.22.5
|
||||
)
|
|
@ -0,0 +1,102 @@
|
|||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da h1:KjTM2ks9d14ZYCvmHS9iAKVt9AyzRSqNU1qabPih5BY=
|
||||
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da/go.mod h1:eHEWzANqSiWQsof+nXEI9bUVUyV6F53Fp89EuCh2EAA=
|
||||
github.com/aead/poly1305 v0.0.0-20180717145839-3fee0db0b635 h1:52m0LGchQBBVqJRyYYufQuIbVqRawmubW3OFGqK1ekw=
|
||||
github.com/aead/poly1305 v0.0.0-20180717145839-3fee0db0b635/go.mod h1:lmLxL+FV291OopO93Bwf9fQLQeLyt33VJRUg5VJ30us=
|
||||
github.com/ameshkov/dnscrypt v1.1.0 h1:2vAt5dD6ZmqlAxEAfzRcLBnkvdf8NI46Kn9InSwQbSI=
|
||||
github.com/ameshkov/dnscrypt v1.1.0/go.mod h1:ikduAxNLCTEfd1AaCgpIA5TgroIVQ8JY3Vb095fiFJg=
|
||||
github.com/ameshkov/dnsstamps v1.0.1/go.mod h1:Ii3eUu73dx4Vw5O4wjzmT5+lkCwovjzaEZZ4gKyIH5A=
|
||||
github.com/ameshkov/dnsstamps v1.0.3 h1:Srzik+J9mivH1alRACTbys2xOxs0lRH9qnTA7Y1OYVo=
|
||||
github.com/ameshkov/dnsstamps v1.0.3/go.mod h1:Ii3eUu73dx4Vw5O4wjzmT5+lkCwovjzaEZZ4gKyIH5A=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
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/denverdino/aliyungo v0.0.0-20210518071019-eb3bbb144d8a h1:J9+NI0ywi1btTOYseLdmr/H3XxutbC4m2bU48kKpwVs=
|
||||
github.com/denverdino/aliyungo v0.0.0-20210518071019-eb3bbb144d8a/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0=
|
||||
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
|
||||
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/go-chi/chi v1.5.3/go.mod h1:Q8xfe6s3fjZyMr8ZTv5jL+vxhVaFyCq2s+RvSfzTD0E=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/honwen/golibs v0.1.4 h1:7B0gXElZex11CVfNs6p9jn7uj/DFroQgI4GIcrh9Wac=
|
||||
github.com/honwen/golibs v0.1.4/go.mod h1:BqdA1MZSiyB9msXACcDNxUn17DSReiIvUWARfpzPI30=
|
||||
github.com/honwen/ip2loc v0.1.2 h1:YgIK6A6iBynOlh2tzYRKl8mGmFoHcPPwws5Q0Ar4lwM=
|
||||
github.com/honwen/ip2loc v0.1.2/go.mod h1:4loWbEvIxSNNr6pDp2YfPnAnJN/SKN7LiHfFr0rHB9o=
|
||||
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
||||
github.com/knadh/koanf v0.14.0/go.mod h1:H5mEFsTeWizwFXHKtsITL5ipsLTuAMQoGuQpp+1JL9U=
|
||||
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/miekg/dns v1.1.29/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
||||
github.com/miekg/dns v1.1.35/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
||||
github.com/miekg/dns v1.1.41 h1:WMszZWJG0XmzbK9FEmzH2TVcqYzFesusSIB41b8KHxY=
|
||||
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
|
||||
github.com/mitchellh/mapstructure v1.2.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/mr-karan/doggo v0.4.0 h1:d5z93qsmEnWLZ2iNn5uBlN70R71wk9RraD02x0kTt/g=
|
||||
github.com/mr-karan/doggo v0.4.0/go.mod h1:Fr8UVbK1pBT1p3hXjF0dWDKQ+K096siHYnXT0Em0btA=
|
||||
github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
|
||||
github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
|
||||
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/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ=
|
||||
github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc=
|
||||
github.com/rhnvrm/simples3 v0.5.0/go.mod h1:Y+3vYm2V7Y4VijFoJHHTrja6OgPrJ2cBti8dPGkC3sA=
|
||||
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/urfave/cli v1.22.5 h1:lNq9sAHXK2qfdI8W+GRItjCEkI+2oR4d+MEHy1CKXoU=
|
||||
github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
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-20200323165209-0ec3e9974c59 h1:3zb4D3T4G8jdExgVU/95+vQXfpEPiMdCaZgmGVxjNHM=
|
||||
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
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-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210502030024-e5908800b52b h1:jCRjgm6WJHzM8VQrm/es2wXYqqbq0NZ1yXFHHgzkiVQ=
|
||||
golang.org/x/net v0.0.0-20210502030024-e5908800b52b/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
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-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/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-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da h1:b3NXsE2LusjYGGjL5bxEVZZORm/YEFFrWFjR8eFrw/c=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
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/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
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/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
@ -0,0 +1,400 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"math/rand"
|
||||
"os"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/denverdino/aliyungo/common"
|
||||
dns "github.com/honwen/aliyun-ddns-cli/alidns"
|
||||
"github.com/honwen/golibs/cip"
|
||||
"github.com/honwen/golibs/domain"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
// AccessKey from https://ak-console.aliyun.com/#/accesskey
|
||||
type AccessKey struct {
|
||||
ID string
|
||||
Secret string
|
||||
client *dns.Client
|
||||
}
|
||||
|
||||
func (ak *AccessKey) getClient() *dns.Client {
|
||||
if len(ak.ID) <= 0 && len(ak.Secret) <= 0 {
|
||||
return nil
|
||||
}
|
||||
if ak.client == nil {
|
||||
ak.client = dns.NewClient(ak.ID, ak.Secret)
|
||||
ak.client.SetEndpoint(dns.DNSDefaultEndpointNew)
|
||||
}
|
||||
return ak.client
|
||||
}
|
||||
|
||||
func (ak AccessKey) String() string {
|
||||
return fmt.Sprintf("Access Key: [ ID: %s ;\t Secret: %s ]", ak.ID, ak.Secret)
|
||||
}
|
||||
|
||||
func (ak *AccessKey) ListRecord(domain string) (dnsRecords []dns.RecordTypeNew, err error) {
|
||||
var resp *dns.DescribeDomainRecordsNewResponse
|
||||
for idx := 1; idx <= 99; idx++ {
|
||||
resp, err = ak.getClient().DescribeDomainRecordsNew(
|
||||
&dns.DescribeDomainRecordsNewArgs{
|
||||
DomainName: domain,
|
||||
Pagination: common.Pagination{PageNumber: idx, PageSize: 50},
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
dnsRecords = append(dnsRecords, resp.DomainRecords.Record...)
|
||||
if len(dnsRecords) >= resp.PaginationResult.TotalCount {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (ak *AccessKey) DelRecord(rr, domain string) (err error) {
|
||||
var target *dns.RecordTypeNew
|
||||
if dnsRecords, err := ak.ListRecord(domain); err == nil {
|
||||
for i := range dnsRecords {
|
||||
if dnsRecords[i].RR == rr {
|
||||
target = &dnsRecords[i]
|
||||
_, err = ak.getClient().DeleteDomainRecord(
|
||||
&dns.DeleteDomainRecordArgs{
|
||||
RecordId: target.RecordId,
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (ak *AccessKey) UpdateRecord(recordID, rr, dmType, value string) (err error) {
|
||||
_, err = ak.getClient().UpdateDomainRecord(
|
||||
&dns.UpdateDomainRecordArgs{
|
||||
RecordId: recordID,
|
||||
RR: rr,
|
||||
Value: value,
|
||||
Type: dmType,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
func (ak *AccessKey) AddRecord(domain, rr, dmType, value string) (err error) {
|
||||
_, err = ak.getClient().AddDomainRecord(
|
||||
&dns.AddDomainRecordArgs{
|
||||
DomainName: domain,
|
||||
RR: rr,
|
||||
Type: dmType,
|
||||
Value: value,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
func (ak *AccessKey) CheckAndUpdateRecord(rr, domain, ipaddr, recordType string) (err error) {
|
||||
fulldomain := strings.Join([]string{rr, domain}, `.`)
|
||||
if reslove(fulldomain) == ipaddr {
|
||||
return // Skip
|
||||
}
|
||||
targetCnt := 0
|
||||
var target *dns.RecordTypeNew
|
||||
if dnsRecords, err := ak.ListRecord(domain); err == nil {
|
||||
for i := range dnsRecords {
|
||||
if dnsRecords[i].RR == rr && dnsRecords[i].Type == recordType {
|
||||
target = &dnsRecords[i]
|
||||
targetCnt++
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
|
||||
if targetCnt > 1 {
|
||||
ak.DelRecord(rr, domain)
|
||||
target = nil
|
||||
}
|
||||
|
||||
if target == nil {
|
||||
err = ak.AddRecord(domain, rr, recordType, ipaddr)
|
||||
} else if target.Value != ipaddr {
|
||||
if target.Type != recordType {
|
||||
return fmt.Errorf("record type error! oldType=%s, targetType=%s", target.Type, recordType)
|
||||
}
|
||||
err = ak.UpdateRecord(target.RecordId, target.RR, target.Type, ipaddr)
|
||||
}
|
||||
if err != nil && strings.Contains(err.Error(), `DomainRecordDuplicate`) {
|
||||
ak.DelRecord(rr, domain)
|
||||
return ak.CheckAndUpdateRecord(rr, domain, ipaddr, recordType)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
var (
|
||||
accessKey AccessKey
|
||||
VersionString = "MISSING build version [git hash]"
|
||||
)
|
||||
|
||||
func init() {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
}
|
||||
|
||||
func main() {
|
||||
app := cli.NewApp()
|
||||
app.Name = "aliddns"
|
||||
app.Usage = "aliyun-ddns-cli"
|
||||
app.Version = fmt.Sprintf("Git:[%s] (%s)", strings.ToUpper(VersionString), runtime.Version())
|
||||
app.Commands = []cli.Command{
|
||||
{
|
||||
Name: "list",
|
||||
Category: "DDNS",
|
||||
Usage: "List AliYun's DNS DomainRecords Record",
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "domain, d",
|
||||
Usage: "Specific `DomainName`. like aliyun.com",
|
||||
},
|
||||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
if err := appInit(c, true); err != nil {
|
||||
return err
|
||||
}
|
||||
// fmt.Println(c.Command.Name, "task: ", accessKey, c.String("domain"))
|
||||
_, domain := domain.SplitDomainToRR(c.String("domain"))
|
||||
if dnsRecords, err := accessKey.ListRecord(domain); err != nil {
|
||||
fmt.Printf("%+v", err)
|
||||
} else {
|
||||
for _, v := range dnsRecords {
|
||||
fmt.Printf("%20s %-8s %s\n", v.RR+`.`+v.DomainName, v.Type, v.Value)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "delete",
|
||||
Category: "DDNS",
|
||||
Usage: "Delete AliYun's DNS DomainRecords Record",
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "domain, d",
|
||||
Usage: "Specific `FullDomainName`. like ddns.aliyun.com",
|
||||
},
|
||||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
if err := appInit(c, true); err != nil {
|
||||
return err
|
||||
}
|
||||
// fmt.Println(c.Command.Name, "task: ", accessKey, c.String("domain"))
|
||||
if err := accessKey.DelRecord(domain.SplitDomainToRR(c.String("domain"))); err != nil {
|
||||
fmt.Printf("%+v", err)
|
||||
} else {
|
||||
fmt.Println(c.String("domain"), "Deleted")
|
||||
}
|
||||
return nil
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "update",
|
||||
Category: "DDNS",
|
||||
Usage: "Update AliYun's DNS DomainRecords Record, Create Record if not exist",
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "domain, d",
|
||||
Usage: "Specific `DomainName`. like ddns.aliyun.com",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "ipaddr, i",
|
||||
Usage: "Specific `IP`. like 1.2.3.4",
|
||||
},
|
||||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
if err := appInit(c, true); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println(c.Command.Name, "task: ", accessKey, c.String("domain"), c.String("ipaddr"))
|
||||
rr, domain := domain.SplitDomainToRR(c.String("domain"))
|
||||
recordType := "A"
|
||||
if c.GlobalBool("ipv6") {
|
||||
recordType = "AAAA"
|
||||
}
|
||||
if err := accessKey.CheckAndUpdateRecord(rr, domain, c.String("ipaddr"), recordType); err != nil {
|
||||
log.Printf("%+v", err)
|
||||
} else {
|
||||
log.Println(c.String("domain"), c.String("ipaddr"), ip2locCN(c.String("ipaddr")))
|
||||
}
|
||||
return nil
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "auto-update",
|
||||
Category: "DDNS",
|
||||
Usage: "Auto-Update AliYun's DNS DomainRecords Record, Get IP using its getip",
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "domain, d",
|
||||
Usage: "Specific `DomainName`. like ddns.aliyun.com",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "redo, r",
|
||||
Value: "",
|
||||
Usage: "redo Auto-Update, every N `Seconds`; Disable if N less than 10; End with [Rr] enable random delay: [N, 2N]",
|
||||
},
|
||||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
if err := appInit(c, true); err != nil {
|
||||
return err
|
||||
}
|
||||
// fmt.Println(c.Command.Name, "task: ", accessKey, c.String("domain"), c.Int64("redo"))
|
||||
rr, domain := domain.SplitDomainToRR(c.String("domain"))
|
||||
recordType := "A"
|
||||
if c.GlobalBool("ipv6") {
|
||||
recordType = "AAAA"
|
||||
}
|
||||
redoDurtionStr := c.String("redo")
|
||||
if len(redoDurtionStr) > 0 && !regexp.MustCompile(`\d+[Rr]?$`).MatchString(redoDurtionStr) {
|
||||
return errors.New(`redo format: [0-9]+[Rr]?$`)
|
||||
}
|
||||
randomDelay := regexp.MustCompile(`\d+[Rr]$`).MatchString(redoDurtionStr)
|
||||
redoDurtion := 0
|
||||
if randomDelay {
|
||||
redoDurtion, _ = strconv.Atoi(redoDurtionStr[:len(redoDurtionStr)-1])
|
||||
} else {
|
||||
redoDurtion, _ = strconv.Atoi(redoDurtionStr)
|
||||
}
|
||||
// Print Version if exist
|
||||
if redoDurtion > 0 && !strings.HasPrefix(VersionString, "MISSING") {
|
||||
fmt.Fprintf(os.Stderr, "%s %s\n", strings.ToUpper(c.App.Name), c.App.Version)
|
||||
}
|
||||
for {
|
||||
autoip := myip()
|
||||
if len(autoip) == 0 {
|
||||
log.Printf("# Err-CheckAndUpdateRecord: [%s]", "IP is empty, PLZ check network")
|
||||
} else {
|
||||
if err := accessKey.CheckAndUpdateRecord(rr, domain, autoip, recordType); err != nil {
|
||||
log.Printf("# Err-CheckAndUpdateRecord: [%+v]", err)
|
||||
} else {
|
||||
log.Println(c.String("domain"), autoip, ip2locCN(autoip))
|
||||
}
|
||||
}
|
||||
if redoDurtion < 10 {
|
||||
break // Disable if N less than 10
|
||||
}
|
||||
if randomDelay {
|
||||
time.Sleep(time.Duration(redoDurtion+rand.Intn(redoDurtion)) * time.Second)
|
||||
} else {
|
||||
time.Sleep(time.Duration(redoDurtion) * time.Second)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "getip",
|
||||
Category: "GET-IP",
|
||||
Usage: fmt.Sprintf(" Get IP Combine 10+ different Web-API"),
|
||||
Action: func(c *cli.Context) error {
|
||||
if err := appInit(c, false); err != nil {
|
||||
return err
|
||||
}
|
||||
// fmt.Println(c.Command.Name, "task: ", c.Command.Usage)
|
||||
ip := myip()
|
||||
fmt.Println(ip, ip2locCN(ip))
|
||||
return nil
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "resolve",
|
||||
Category: "GET-IP",
|
||||
Usage: fmt.Sprintf(" Get DNS-IPv4 Combine 4+ DNS Upstream"),
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "domain, d",
|
||||
Usage: "Specific `DomainName`. like ddns.aliyun.com",
|
||||
},
|
||||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
if err := appInit(c, false); err != nil {
|
||||
return err
|
||||
}
|
||||
// fmt.Println(c.Command.Name, "task: ", c.Command.Usage)
|
||||
ip := reslove(c.String("domain"))
|
||||
fmt.Println(ip, ip2locCN(ip))
|
||||
return nil
|
||||
},
|
||||
},
|
||||
}
|
||||
app.Flags = []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "access-key-id, id",
|
||||
Usage: "AliYun's Access Key ID",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "access-key-secret, secret",
|
||||
Usage: "AliYun's Access Key Secret",
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Name: "ipapi, api",
|
||||
Usage: "Web-API to Get IP, like: http://myip.ipip.net",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "ipv6, 6",
|
||||
Usage: "IPv6",
|
||||
},
|
||||
}
|
||||
app.Action = func(c *cli.Context) error {
|
||||
return appInit(c, true)
|
||||
}
|
||||
app.Run(os.Args)
|
||||
}
|
||||
|
||||
func appInit(c *cli.Context, checkAccessKey bool) error {
|
||||
akids := []string{c.GlobalString("access-key-id"), os.Getenv("AKID"), os.Getenv("AccessKeyID")}
|
||||
akscts := []string{c.GlobalString("access-key-secret"), os.Getenv("AKSCT"), os.Getenv("AccessKeySecret")}
|
||||
sort.Sort(sort.Reverse(sort.StringSlice(akids)))
|
||||
sort.Sort(sort.Reverse(sort.StringSlice(akscts)))
|
||||
accessKey.ID = akids[0]
|
||||
accessKey.Secret = akscts[0]
|
||||
if checkAccessKey && accessKey.getClient() == nil {
|
||||
cli.ShowAppHelp(c)
|
||||
return errors.New("access-key is empty")
|
||||
}
|
||||
|
||||
if c.GlobalBool("ipv6") {
|
||||
funcs["myip"] = cip.MyIPv6
|
||||
funcs["reslove"] = cip.ResloveIPv6
|
||||
}
|
||||
|
||||
ipapi := []string{}
|
||||
for _, api := range c.GlobalStringSlice("ipapi") {
|
||||
if !regexp.MustCompile(`^https?://.*`).MatchString(api) {
|
||||
api = "http://" + api
|
||||
}
|
||||
if regexp.MustCompile(`(https?|ftp|file)://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]`).MatchString(api) {
|
||||
ipapi = append(ipapi, api)
|
||||
}
|
||||
}
|
||||
if len(ipapi) > 0 {
|
||||
regx := regexp.MustCompile(cip.RegxIPv4)
|
||||
if c.GlobalBoolT("ipv6") {
|
||||
regx = regexp.MustCompile(cip.RegxIPv6)
|
||||
}
|
||||
funcs["myip"] = func() string {
|
||||
return cip.FastWGetWithVailder(ipapi, func(s string) string {
|
||||
return regx.FindString((s))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/honwen/golibs/cip"
|
||||
"github.com/honwen/ip2loc"
|
||||
)
|
||||
|
||||
var funcs = map[string]interface{}{
|
||||
"myip": cip.MyIPv4,
|
||||
"reslove": cip.ResloveIPv4,
|
||||
}
|
||||
|
||||
func ip2locCN(ip string) (str string) {
|
||||
if strings.Count(ip, `.`) < 3 {
|
||||
return
|
||||
}
|
||||
if loc, err := ip2loc.IP2loc(ip); err != nil {
|
||||
log.Printf("%+v", err)
|
||||
} else {
|
||||
str = fmt.Sprintf("[%s %s %s %s]", loc.CountryName, loc.RegionName, loc.CityName, loc.IspDomain)
|
||||
for strings.Contains(str, " ]") {
|
||||
str = strings.ReplaceAll(str, " ]", "]")
|
||||
}
|
||||
for strings.Contains(str, " ") {
|
||||
str = strings.ReplaceAll(str, " ", " ")
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func Call(m map[string]interface{}, name string, params ...interface{}) (result []reflect.Value, err error) {
|
||||
f := reflect.ValueOf(m[name])
|
||||
if len(params) != f.Type().NumIn() {
|
||||
err = errors.New("The number of params is not adapted.")
|
||||
return
|
||||
}
|
||||
|
||||
in := make([]reflect.Value, len(params))
|
||||
for k, param := range params {
|
||||
in[k] = reflect.ValueOf(param)
|
||||
}
|
||||
result = f.Call(in)
|
||||
return
|
||||
}
|
||||
|
||||
func myip() (ip string) {
|
||||
if result, err := Call(funcs, "myip"); err == nil {
|
||||
for _, r := range result {
|
||||
return r.String()
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func reslove(domain string) (ip string) {
|
||||
if result, err := Call(funcs, "reslove", domain); err == nil {
|
||||
for _, r := range result {
|
||||
return r.String()
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"testing"
|
||||
|
||||
"github.com/honwen/golibs/cip"
|
||||
"github.com/honwen/golibs/domain"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestIp2locCN(t *testing.T) {
|
||||
assert.Equal(t, ip2locCN("202.96.128.86"), "[中国 广东 广州 电信]")
|
||||
assert.Equal(t, ip2locCN("202.96.209.133"), "[中国 上海 上海 电信]")
|
||||
assert.Equal(t, ip2locCN("219.141.136.10"), "[中国 北京 北京 电信]")
|
||||
|
||||
assert.Equal(t, ip2locCN("210.22.70.3"), "[中国 上海 上海 联通]")
|
||||
assert.Equal(t, ip2locCN("123.123.123.123"), "[中国 北京 北京 联通]")
|
||||
|
||||
assert.Equal(t, ip2locCN("223.87.238.22"), "[中国 四川 成都 移动]")
|
||||
|
||||
assert.Equal(t, ip2locCN("101.6.6.6"), "[中国 北京 北京 教育网]")
|
||||
|
||||
assert.Equal(t, ip2locCN("168.95.1.1"), "[中国 台湾 中华电信]")
|
||||
assert.Equal(t, ip2locCN("202.67.240.222"), "[中国 香港]")
|
||||
|
||||
assert.Equal(t, ip2locCN("203.189.136.148"), "[柬埔寨 柬埔寨]")
|
||||
assert.Equal(t, ip2locCN("203.112.2.4"), "[日本 日本]")
|
||||
assert.Equal(t, ip2locCN("80.80.80.80"), "[荷兰 荷兰]")
|
||||
assert.Equal(t, ip2locCN("74.82.42.42"), "[美国 加利福尼亚州]")
|
||||
|
||||
}
|
||||
|
||||
func TestGetIPv4(t *testing.T) {
|
||||
funcs["myip"] = cip.MyIPv4
|
||||
ip4 := myip()
|
||||
assert.True(t, regexp.MustCompile(cip.RegxIPv4).MatchString(ip4) || len(ip4) == 0)
|
||||
}
|
||||
|
||||
func TestGetIPv6(t *testing.T) {
|
||||
funcs["myip"] = cip.MyIPv6
|
||||
ip6 := myip()
|
||||
assert.True(t, regexp.MustCompile(cip.RegxIPv6).MatchString(ip6) || len(ip6) == 0)
|
||||
}
|
||||
|
||||
func TestResloveIPv4(t *testing.T) {
|
||||
funcs["reslove"] = cip.ResloveIPv4
|
||||
assert.Contains(t, []string{"8.8.8.8", "8.8.4.4"}, reslove("dns.google"))
|
||||
assert.Contains(t, []string{"223.6.6.6", "223.5.5.5"}, reslove("dns.alidns.com"))
|
||||
}
|
||||
|
||||
func TestResloveIPv6(t *testing.T) {
|
||||
funcs["reslove"] = cip.ResloveIPv6
|
||||
assert.Contains(t, []string{"2001:4860:4860::8844", "2001:4860:4860::8888"}, reslove("dns.google"))
|
||||
assert.Contains(t, []string{"2400:3200::1", "2400:3200:baba::1"}, reslove("dns.alidns.com"))
|
||||
}
|
||||
|
||||
func TestSplitDomain001(t *testing.T) {
|
||||
rr, domain := domain.SplitDomainToRR("a.example.com")
|
||||
|
||||
assert.Equal(t, rr, "a")
|
||||
assert.Equal(t, domain, "example.com")
|
||||
}
|
||||
|
||||
func TestSplitDomain002(t *testing.T) {
|
||||
rr, domain := domain.SplitDomainToRR("example.com")
|
||||
|
||||
assert.Equal(t, rr, "@")
|
||||
assert.Equal(t, domain, "example.com")
|
||||
}
|
||||
|
||||
func TestSplitDomain003(t *testing.T) {
|
||||
rr, domain := domain.SplitDomainToRR("*.example.com")
|
||||
|
||||
assert.Equal(t, rr, "*")
|
||||
assert.Equal(t, domain, "example.com")
|
||||
}
|
||||
|
||||
func TestSplitDomain004(t *testing.T) {
|
||||
rr, domain := domain.SplitDomainToRR("*.a.example.com")
|
||||
|
||||
assert.Equal(t, rr, "*.a")
|
||||
assert.Equal(t, domain, "example.com")
|
||||
}
|
||||
|
||||
func TestSplitDomain005(t *testing.T) {
|
||||
rr, domain := domain.SplitDomainToRR("*.b.a.example.com")
|
||||
|
||||
assert.Equal(t, rr, "*.b.a")
|
||||
assert.Equal(t, domain, "example.com")
|
||||
}
|
||||
func TestSplitDomain006(t *testing.T) {
|
||||
rr, domain := domain.SplitDomainToRR("a.example.co.kr")
|
||||
|
||||
assert.Equal(t, rr, "a")
|
||||
assert.Equal(t, domain, "example.co.kr")
|
||||
}
|
||||
|
||||
func TestSplitDomain007(t *testing.T) {
|
||||
rr, domain := domain.SplitDomainToRR("*.a.example.co.kr")
|
||||
|
||||
assert.Equal(t, rr, "*.a")
|
||||
assert.Equal(t, domain, "example.co.kr")
|
||||
}
|
||||
|
||||
func TestSplitDomain008(t *testing.T) {
|
||||
rr, domain := domain.SplitDomainToRR("example.co.kr")
|
||||
|
||||
assert.Equal(t, rr, "@")
|
||||
assert.Equal(t, domain, "example.co.kr")
|
||||
}
|
Loading…
Reference in New Issue