diff --git a/ddns-aliyun/.dockerignore b/ddns-aliyun/.dockerignore new file mode 100644 index 0000000..3b0b1d2 --- /dev/null +++ b/ddns-aliyun/.dockerignore @@ -0,0 +1,12 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +.vscode/ +.github/ +release/ +build/ +vendor/ + +Dockerfile diff --git a/ddns-aliyun/.github/workflows/build.yaml b/ddns-aliyun/.github/workflows/build.yaml index 3737a67..aae9b4d 100644 --- a/ddns-aliyun/.github/workflows/build.yaml +++ b/ddns-aliyun/.github/workflows/build.yaml @@ -18,7 +18,7 @@ jobs: - uses: actions/setup-go@v2 with: - go-version: 1.16.4 + go-version: 1.17.6 - name: Prepare environment run: |- @@ -34,9 +34,11 @@ jobs: # Win - run: GOOS=windows GOARCH=386 VERSION=${RELEASE_VERSION} make release - run: GOOS=windows GOARCH=amd64 VERSION=${RELEASE_VERSION} make release + - run: GOOS=windows GOARCH=arm64 VERSION=${RELEASE_VERSION} make release # MacOS - run: GOOS=darwin GOARCH=amd64 VERSION=${RELEASE_VERSION} make release + - run: GOOS=darwin GOARCH=arm64 VERSION=${RELEASE_VERSION} make release # Linux X86/AMD64 - run: GOOS=linux GOARCH=386 VERSION=${RELEASE_VERSION} make release diff --git a/ddns-aliyun/Dockerfile b/ddns-aliyun/Dockerfile index 86ed83c..191c1f1 100644 --- a/ddns-aliyun/Dockerfile +++ b/ddns-aliyun/Dockerfile @@ -1,31 +1,29 @@ -FROM golang:alpine as builder -ENV CGO_ENABLED=0 \ - GO111MODULE=on - -RUN apk add --update git curl -ADD . $GOPATH/src/github.com/honwen/aliyun-ddns-cli +FROM golang as builder +WORKDIR /builder +ADD . . 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/ + && 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 -n1 | tee .version \ + && go mod vendor \ + && GOOS=linux GOARCH=amd64 VERSION=$(cat .version) make release FROM alpine LABEL MAINTAINER honwen # /usr/bin/aliyun-ddns-cli -COPY --from=builder /go/bin /usr/bin +COPY --from=builder /builder/build/linux-amd64/aliddns /usr/bin/aliyun-ddns-cli ENV AKID=1234567890 \ AKSCT=abcdefghijklmn \ DOMAIN=ddns.example.win \ IPAPI=[IPAPI-GROUP] \ - REDO=0 + REDO=555r \ + TTL=600 CMD aliyun-ddns-cli \ --ipapi ${IPAPI} \ ${IPV6:+-6} \ auto-update \ --domain ${DOMAIN} \ - --redo ${REDO} + --redo ${REDO} \ + --ttl ${TTL} diff --git a/ddns-aliyun/LICENSE b/ddns-aliyun/LICENSE index 346ea2f..44b80db 100644 --- a/ddns-aliyun/LICENSE +++ b/ddns-aliyun/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2016-2020 honwen +Copyright (c) 2016-2021 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 diff --git a/ddns-aliyun/alidns/AddDomainRecord.go b/ddns-aliyun/alidns/AddDomainRecord.go index caed84b..92c8e17 100644 --- a/ddns-aliyun/alidns/AddDomainRecord.go +++ b/ddns-aliyun/alidns/AddDomainRecord.go @@ -1,6 +1,7 @@ package dns import ( + "encoding/json" "log" "github.com/denverdino/aliyungo/common" @@ -13,6 +14,7 @@ type AddDomainRecordArgs struct { Value string //optional + TTL json.Number Line string } diff --git a/ddns-aliyun/alidns/AddDomainRecord_test.go b/ddns-aliyun/alidns/AddDomainRecord_test.go index e8e6c5b..7d58d53 100644 --- a/ddns-aliyun/alidns/AddDomainRecord_test.go +++ b/ddns-aliyun/alidns/AddDomainRecord_test.go @@ -11,6 +11,7 @@ func TestAddDomainRecord(t *testing.T) { RR: "testaddrecord", Type: ARecord, Value: "8.8.8.8", + TTL: "600" } response, err := client.AddDomainRecord(&addDomainRecordArgs) if err == nil { diff --git a/ddns-aliyun/alidns/DeleteDomainRecord_test.go b/ddns-aliyun/alidns/DeleteDomainRecord_test.go index e6d2e3f..356c013 100644 --- a/ddns-aliyun/alidns/DeleteDomainRecord_test.go +++ b/ddns-aliyun/alidns/DeleteDomainRecord_test.go @@ -12,6 +12,7 @@ func TestDeleteDomainRecord(t *testing.T) { RR: "testdeleterecordid", Type: ARecord, Value: "8.8.8.8", + TTL: "600", } addResponse, err := client.AddDomainRecord(&addDomainRecordArgs) diff --git a/ddns-aliyun/alidns/DeleteSubDomainRecords_test.go b/ddns-aliyun/alidns/DeleteSubDomainRecords_test.go index d21eacf..a174a70 100644 --- a/ddns-aliyun/alidns/DeleteSubDomainRecords_test.go +++ b/ddns-aliyun/alidns/DeleteSubDomainRecords_test.go @@ -12,6 +12,7 @@ func TestDeleteSubDomainRecords(t *testing.T) { RR: "testdeletesubdomainrecords", Type: ARecord, Value: "8.8.8.8", + TTL: "600", } client.AddDomainRecord(&addDomainRecordArgs) diff --git a/ddns-aliyun/alidns/DescribeDomainRecordInfoNew.go b/ddns-aliyun/alidns/DescribeDomainRecordInfoNew.go index 8eed446..26fda3c 100644 --- a/ddns-aliyun/alidns/DescribeDomainRecordInfoNew.go +++ b/ddns-aliyun/alidns/DescribeDomainRecordInfoNew.go @@ -1,6 +1,10 @@ package dns -import "github.com/denverdino/aliyungo/common" +import ( + "encoding/json" + + "github.com/denverdino/aliyungo/common" +) // endpoint change to 'http://alidns.aliyuncs.com' then record ttl and priority change to string type RecordTypeNew struct { @@ -9,6 +13,7 @@ type RecordTypeNew struct { RR string Type string Value string + TTL json.Number Line string Status string Locked bool diff --git a/ddns-aliyun/alidns/UpdateDomainRecord.go b/ddns-aliyun/alidns/UpdateDomainRecord.go index ba32173..4d40100 100644 --- a/ddns-aliyun/alidns/UpdateDomainRecord.go +++ b/ddns-aliyun/alidns/UpdateDomainRecord.go @@ -1,6 +1,10 @@ package dns -import "github.com/denverdino/aliyungo/common" +import ( + "encoding/json" + + "github.com/denverdino/aliyungo/common" +) type UpdateDomainRecordArgs struct { RecordId string @@ -9,8 +13,8 @@ type UpdateDomainRecordArgs struct { Value string //optional - TTL int32 - Priority int32 + TTL json.Number + Priority json.Number Line string } diff --git a/ddns-aliyun/alidns/UpdateDomainRecord_test.go b/ddns-aliyun/alidns/UpdateDomainRecord_test.go index 59f4ff9..206e341 100644 --- a/ddns-aliyun/alidns/UpdateDomainRecord_test.go +++ b/ddns-aliyun/alidns/UpdateDomainRecord_test.go @@ -12,6 +12,7 @@ func TestUpdateDomainRecord(t *testing.T) { RR: "testupdaterecordid", Value: "8.8.8.8", Type: ARecord, + TTL: "600", } addResponse, err := client.AddDomainRecord(&addDomainRecordArgs) @@ -22,6 +23,7 @@ func TestUpdateDomainRecord(t *testing.T) { RR: addDomainRecordArgs.RR, Value: "4.4.4.4", Type: ARecord, + TTL: "600", } _, err = client.UpdateDomainRecord(&updateArgs) diff --git a/ddns-aliyun/alidns/record.go b/ddns-aliyun/alidns/record.go index 5e306f7..7b5551a 100644 --- a/ddns-aliyun/alidns/record.go +++ b/ddns-aliyun/alidns/record.go @@ -1,5 +1,7 @@ package dns +import "encoding/json" + // //you can read doc at https://docs.aliyun.com/#/pub/dns/api-reference/enum-type&record-format const ( @@ -20,8 +22,8 @@ type RecordType struct { RR string Type string Value string - TTL int32 - Priority int32 + TTL json.Number + Priority json.Number Line string Status string Locked bool diff --git a/ddns-aliyun/go.mod b/ddns-aliyun/go.mod index a6c4e6a..a9834f0 100644 --- a/ddns-aliyun/go.mod +++ b/ddns-aliyun/go.mod @@ -3,9 +3,9 @@ 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/denverdino/aliyungo v0.0.0-20211216041018-95e021eb8eb7 + github.com/honwen/golibs v0.2.5 + github.com/honwen/ip2loc v0.2.0 github.com/stretchr/testify v1.7.0 github.com/urfave/cli v1.22.5 ) diff --git a/ddns-aliyun/go.sum b/ddns-aliyun/go.sum index a175d6b..c587431 100644 --- a/ddns-aliyun/go.sum +++ b/ddns-aliyun/go.sum @@ -1,44 +1,53 @@ +github.com/AdguardTeam/golibs v0.4.2 h1:7M28oTZFoFwNmp8eGPb3ImmYbxGaJLyQXeIFVHjME0o= +github.com/AdguardTeam/golibs v0.4.2/go.mod h1:skKsDKIBB7kkFflLJBpfGX+G8QFTx0WKUzB6TIgtUj4= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/PuerkitoBio/goquery v1.7.1 h1:oE+T06D+1T7LNrn91B4aERsRIeCLJ/oPSa6xB9FPnz4= +github.com/PuerkitoBio/goquery v1.7.1/go.mod h1:XY0pP4kfraEmmV1O7Uf6XyjoslwsneBbgeDjLYuN8xY= +github.com/Workiva/go-datastructures v1.0.53 h1:J6Y/52yX10Xc5JjXmGtWoSSxs3mZnGSaq37xZZh7Yig= +github.com/Workiva/go-datastructures v1.0.53/go.mod h1:1yZL+zfsztete+ePzZz/Zb1/t5BnDuE2Ya2MMGhzP6A= 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/dnscrypt/v2 v2.2.1 h1:+cApRxzeBZqjUNsN26TTz7r5A8U+buON3kJgIYE3QWQ= +github.com/ameshkov/dnscrypt/v2 v2.2.1/go.mod h1:+8SbPbVXpxxcUsgGi8eodkqWPo1MyNHxKYC8hDpqLSo= 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/andybalholm/cascadia v1.2.0 h1:vuRCkM5Ozh/BfmsaTm26kbjm0mIOM3yS5Ek/F5h18aE= +github.com/andybalholm/cascadia v1.2.0/go.mod h1:YCyR8vOZT9aZ1CHEd8ap0gMVm2aFgxBp0T0eFw1RUQY= 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/denverdino/aliyungo v0.0.0-20211216041018-95e021eb8eb7 h1:3x/qbhudvljDh48e2LORoL0Id2mXG7GkcK0rSf3qdHA= +github.com/denverdino/aliyungo v0.0.0-20211216041018-95e021eb8eb7/go.mod h1:VVxx1gyGhdt369208nKOYLI0PVgrZqbU+EuWBZJQ1ZQ= 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/honwen/golibs v0.2.5 h1:eU+HP5pgVeR0uAiytNZBalEWXUZ7PlXkCYQDLT9nCdg= +github.com/honwen/golibs v0.2.5/go.mod h1:H0e+TwcqQtJifgabzZ9BU06GUa2dX1VCzLesnTpEGlA= +github.com/honwen/ip2loc v0.2.0 h1:iFGR7kX0/Ss4Q2UkDcht4CqkqeOg0+vva7ftaEL/lhQ= +github.com/honwen/ip2loc v0.2.0/go.mod h1:4loWbEvIxSNNr6pDp2YfPnAnJN/SKN7LiHfFr0rHB9o= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= 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/miekg/dns v1.1.40/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= +github.com/miekg/dns v1.1.43 h1:JKfpVSCB84vrAmHzyrsxB5NAr5kLoMXZArPSw7Qlgyg= +github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= 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/mr-karan/doggo v0.4.1 h1:n+klWy4Nw/cSAyY4/CLBqzXK6xJ34wPTs7aZJoxcoyQ= +github.com/mr-karan/doggo v0.4.1/go.mod h1:pwor+16oscviGvwzxeSPspEOAb6qAeFzWcb/dppmI7Q= 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/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= 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= @@ -54,24 +63,33 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An 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.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= 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/tinylib/msgp v1.1.5/go.mod h1:eQsjooMTnV42mHu917E26IogZ2930nFyBQdofk10Udg= +github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q= github.com/urfave/cli v1.22.5 h1:lNq9sAHXK2qfdI8W+GRItjCEkI+2oR4d+MEHy1CKXoU= github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 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/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/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-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-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 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/net v0.0.0-20210614182718-04defd469f4e h1:XpT3nA5TvE525Ne3hInMh6+GETgn27Zfm9dxsThnX2Q= +golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 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 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= @@ -83,6 +101,7 @@ golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7w 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-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-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da h1:b3NXsE2LusjYGGjL5bxEVZZORm/YEFFrWFjR8eFrw/c= @@ -92,8 +111,12 @@ 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-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +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-20200804184101-5ec99f83aff1/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= diff --git a/ddns-aliyun/main.go b/ddns-aliyun/main.go index bb1954e..2c7484c 100644 --- a/ddns-aliyun/main.go +++ b/ddns-aliyun/main.go @@ -1,6 +1,7 @@ package main import ( + "encoding/json" "errors" "fmt" "log" @@ -22,9 +23,10 @@ import ( // AccessKey from https://ak-console.aliyun.com/#/accesskey type AccessKey struct { - ID string - Secret string - client *dns.Client + ID string + Secret string + client *dns.Client + managedDomains []string } func (ak *AccessKey) getClient() *dns.Client { @@ -42,6 +44,42 @@ func (ak AccessKey) String() string { return fmt.Sprintf("Access Key: [ ID: %s ;\t Secret: %s ]", ak.ID, ak.Secret) } +func (ak *AccessKey) ListManagedDomains() (domains []string, err error) { + var resp []dns.DomainType + resp, err = ak.getClient().DescribeDomains( + &dns.DescribeDomainsArgs{ + Pagination: common.Pagination{PageSize: 50}, + }) + if err != nil { + return + } + domains = make([]string, len(resp)) + for i, v := range resp { + domains[i] = v.DomainName + } + return +} + +func (ak *AccessKey) AutocheckDomainRR(rr, domain string) (r, d string, err error) { + if contains(ak.managedDomains, domain) { + return rr, domain, nil + } else { + if !strings.Contains(rr, `.`) { + return "", "", fmt.Errorf("Domain [%s.%s] Not Managed", rr, domain) + } else { + rrs := strings.Split(rr, `.`) + for i := len(rrs) - 1; i > 0; i-- { + d = strings.Join(append(rrs[i:], domain), `.`) + if contains(ak.managedDomains, d) { + r = strings.Join(rrs[:i], `.`) + return + } + } + } + } + return "", "", fmt.Errorf("Domain [%s.%s] Not Managed", rr, domain) +} + func (ak *AccessKey) ListRecord(domain string) (dnsRecords []dns.RecordTypeNew, err error) { var resp *dns.DescribeDomainRecordsNewResponse for idx := 1; idx <= 99; idx++ { @@ -80,29 +118,31 @@ func (ak *AccessKey) DelRecord(rr, domain string) (err error) { return } -func (ak *AccessKey) UpdateRecord(recordID, rr, dmType, value string) (err error) { +func (ak *AccessKey) UpdateRecord(recordID, rr, dmType, value string, ttl int) (err error) { _, err = ak.getClient().UpdateDomainRecord( &dns.UpdateDomainRecordArgs{ RecordId: recordID, RR: rr, Value: value, Type: dmType, + TTL: json.Number(fmt.Sprint(ttl)), }) return } -func (ak *AccessKey) AddRecord(domain, rr, dmType, value string) (err error) { +func (ak *AccessKey) AddRecord(domain, rr, dmType, value string, ttl int) (err error) { _, err = ak.getClient().AddDomainRecord( &dns.AddDomainRecordArgs{ DomainName: domain, RR: rr, Type: dmType, Value: value, + TTL: json.Number(fmt.Sprint(ttl)), }) return err } -func (ak *AccessKey) CheckAndUpdateRecord(rr, domain, ipaddr, recordType string) (err error) { +func (ak *AccessKey) CheckAndUpdateRecord(rr, domain, ipaddr, recordType string, ttl int) (err error) { fulldomain := strings.Join([]string{rr, domain}, `.`) if reslove(fulldomain) == ipaddr { return // Skip @@ -126,16 +166,16 @@ func (ak *AccessKey) CheckAndUpdateRecord(rr, domain, ipaddr, recordType string) } if target == nil { - err = ak.AddRecord(domain, rr, recordType, ipaddr) + err = ak.AddRecord(domain, rr, recordType, ipaddr, ttl) } 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) + err = ak.UpdateRecord(target.RecordId, target.RR, target.Type, ipaddr, ttl) } if err != nil && strings.Contains(err.Error(), `DomainRecordDuplicate`) { ak.DelRecord(rr, domain) - return ak.CheckAndUpdateRecord(rr, domain, ipaddr, recordType) + return ak.CheckAndUpdateRecord(rr, domain, ipaddr, recordType, ttl) } return err } @@ -170,12 +210,15 @@ func main() { return err } // fmt.Println(c.Command.Name, "task: ", accessKey, c.String("domain")) - _, domain := domain.SplitDomainToRR(c.String("domain")) + domain := c.String("domain") + if !contains(accessKey.managedDomains, domain) { + return fmt.Errorf("Domain [%s] Not Managed", 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) + fmt.Printf("%20s %-16s %s\n", v.RR+`.`+v.DomainName, fmt.Sprintf("%s(TTL:%4s)", v.Type, v.TTL), v.Value) } } return nil @@ -196,7 +239,11 @@ func main() { return err } // fmt.Println(c.Command.Name, "task: ", accessKey, c.String("domain")) - if err := accessKey.DelRecord(domain.SplitDomainToRR(c.String("domain"))); err != nil { + rr, domain, err := accessKey.AutocheckDomainRR(domain.SplitDomainToRR(c.String("domain"))) + if err != nil { + return err + } + if err := accessKey.DelRecord(rr, domain); err != nil { fmt.Printf("%+v", err) } else { fmt.Println(c.String("domain"), "Deleted") @@ -217,18 +264,26 @@ func main() { Name: "ipaddr, i", Usage: "Specific `IP`. like 1.2.3.4", }, + cli.IntFlag{ + Name: "ttl, t", + Value: 600, + Usage: "The resolution effective time (in `seconds`)", + }, }, 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")) + // fmt.Println(c.Command.Name, "task: ", accessKey, c.String("domain"), c.String("ipaddr")) + rr, domain, err := accessKey.AutocheckDomainRR(domain.SplitDomainToRR(c.String("domain"))) + if err != nil { + return err + } recordType := "A" if c.GlobalBool("ipv6") { recordType = "AAAA" } - if err := accessKey.CheckAndUpdateRecord(rr, domain, c.String("ipaddr"), recordType); err != nil { + if err := accessKey.CheckAndUpdateRecord(rr, domain, c.String("ipaddr"), recordType, c.Int("ttl")); err != nil { log.Printf("%+v", err) } else { log.Println(c.String("domain"), c.String("ipaddr"), ip2locCN(c.String("ipaddr"))) @@ -250,13 +305,21 @@ func main() { Value: "", Usage: "redo Auto-Update, every N `Seconds`; Disable if N less than 10; End with [Rr] enable random delay: [N, 2N]", }, + cli.IntFlag{ + Name: "ttl, t", + Value: 600, + Usage: "The resolution effective time (in `seconds`)", + }, }, 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")) + rr, domain, err := accessKey.AutocheckDomainRR(domain.SplitDomainToRR(c.String("domain"))) + if err != nil { + return err + } recordType := "A" if c.GlobalBool("ipv6") { recordType = "AAAA" @@ -281,7 +344,7 @@ func main() { 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 { + if err := accessKey.CheckAndUpdateRecord(rr, domain, autoip, recordType, c.Int("ttl")); err != nil { log.Printf("# Err-CheckAndUpdateRecord: [%+v]", err) } else { log.Println(c.String("domain"), autoip, ip2locCN(autoip)) @@ -369,6 +432,13 @@ func appInit(c *cli.Context, checkAccessKey bool) error { cli.ShowAppHelp(c) return errors.New("access-key is empty") } + if domains, err := accessKey.ListManagedDomains(); err == nil { + // log.Println(domains) + accessKey.managedDomains = domains + } else { + cli.ShowAppHelp(c) + return errors.New("No Managed Domains") + } if c.GlobalBool("ipv6") { funcs["myip"] = cip.MyIPv6 diff --git a/ddns-aliyun/utils.go b/ddns-aliyun/utils.go index f2b2eb9..85ff084 100644 --- a/ddns-aliyun/utils.go +++ b/ddns-aliyun/utils.go @@ -16,6 +16,15 @@ var funcs = map[string]interface{}{ "reslove": cip.ResloveIPv4, } +func contains(slice []string, item string) bool { + set := make(map[string]struct{}, len(slice)) + for _, s := range slice { + set[s] = struct{}{} + } + _, ok := set[item] + return ok +} + func ip2locCN(ip string) (str string) { if strings.Count(ip, `.`) < 3 { return