mirror of
https://github.com/qdm12/ddns-updater.git
synced 2026-04-05 08:54:09 -04:00
fix(google): removed since no longer functional
- Logs error if provider google is used - Documentation updated - Fixes #605
This commit is contained in:
@@ -52,7 +52,6 @@ Light container updating DNS A and/or AAAA records periodically for multiple DNS
|
|||||||
- Gandi
|
- Gandi
|
||||||
- GCP
|
- GCP
|
||||||
- GoDaddy
|
- GoDaddy
|
||||||
- Google
|
|
||||||
- He.net
|
- He.net
|
||||||
- Hetzner
|
- Hetzner
|
||||||
- Infomaniak
|
- Infomaniak
|
||||||
@@ -191,7 +190,6 @@ Check the documentation for your DNS provider:
|
|||||||
- [Gandi](https://github.com/qdm12/ddns-updater/blob/master/docs/gandi.md)
|
- [Gandi](https://github.com/qdm12/ddns-updater/blob/master/docs/gandi.md)
|
||||||
- [GCP](https://github.com/qdm12/ddns-updater/blob/master/docs/gcp.md)
|
- [GCP](https://github.com/qdm12/ddns-updater/blob/master/docs/gcp.md)
|
||||||
- [GoDaddy](https://github.com/qdm12/ddns-updater/blob/master/docs/godaddy.md)
|
- [GoDaddy](https://github.com/qdm12/ddns-updater/blob/master/docs/godaddy.md)
|
||||||
- [Google](https://github.com/qdm12/ddns-updater/blob/master/docs/google.md)
|
|
||||||
- [He.net](https://github.com/qdm12/ddns-updater/blob/master/docs/he.net.md)
|
- [He.net](https://github.com/qdm12/ddns-updater/blob/master/docs/he.net.md)
|
||||||
- [Infomaniak](https://github.com/qdm12/ddns-updater/blob/master/docs/infomaniak.md)
|
- [Infomaniak](https://github.com/qdm12/ddns-updater/blob/master/docs/infomaniak.md)
|
||||||
- [INWX](https://github.com/qdm12/ddns-updater/blob/master/docs/inwx.md)
|
- [INWX](https://github.com/qdm12/ddns-updater/blob/master/docs/inwx.md)
|
||||||
|
|||||||
@@ -1,42 +0,0 @@
|
|||||||
# Google
|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
|
|
||||||
### Example
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"settings": [
|
|
||||||
{
|
|
||||||
"provider": "google",
|
|
||||||
"domain": "domain.com",
|
|
||||||
"host": "@",
|
|
||||||
"username": "username",
|
|
||||||
"password": "password",
|
|
||||||
"ip_version": "ipv4"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Compulsory parameters
|
|
||||||
|
|
||||||
- `"domain"`
|
|
||||||
- `"host"` is your host and can be a subdomain or `"@"` or `"*"`
|
|
||||||
- `"username"`
|
|
||||||
- `"password"`
|
|
||||||
|
|
||||||
### Optional parameters
|
|
||||||
|
|
||||||
- `"ip_version"` can be `ipv4` (A records) or `ipv6` (AAAA records), defaults to `ipv4 or ipv6`
|
|
||||||
|
|
||||||
## Domain setup
|
|
||||||
|
|
||||||
Thanks to [@gauravspatel](https://github.com/gauravspatel) for #124
|
|
||||||
|
|
||||||
1. Enable dynamic DNS in the *synthetic records* section of DNS management.
|
|
||||||
1. The username and password is generated once you create the dynamic DNS entry.
|
|
||||||
|
|
||||||
### Wildcard entries
|
|
||||||
|
|
||||||
If you want to create a **wildcard entry**, you have to create a custom **CNAME** record with key `"*"` and value `"@"`.
|
|
||||||
@@ -130,8 +130,16 @@ func extractAllSettings(jsonBytes []byte) (
|
|||||||
return allProviders, warnings, nil
|
return allProviders, warnings, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrProviderNoLongerSupported = errors.New("provider no longer supported")
|
||||||
|
)
|
||||||
|
|
||||||
func makeSettingsFromObject(common commonSettings, rawSettings json.RawMessage) (
|
func makeSettingsFromObject(common commonSettings, rawSettings json.RawMessage) (
|
||||||
providers []provider.Provider, warnings []string, err error) {
|
providers []provider.Provider, warnings []string, err error) {
|
||||||
|
if common.Provider == "google" {
|
||||||
|
return nil, nil, fmt.Errorf("%w: %s", ErrProviderNoLongerSupported, common.Provider)
|
||||||
|
}
|
||||||
|
|
||||||
providerName := models.Provider(common.Provider)
|
providerName := models.Provider(common.Provider)
|
||||||
if providerName == constants.DuckDNS { // only hosts, no domain
|
if providerName == constants.DuckDNS { // only hosts, no domain
|
||||||
if common.Domain != "" { // retro compatibility
|
if common.Domain != "" { // retro compatibility
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ const (
|
|||||||
Gandi models.Provider = "gandi"
|
Gandi models.Provider = "gandi"
|
||||||
GCP models.Provider = "gcp"
|
GCP models.Provider = "gcp"
|
||||||
GoDaddy models.Provider = "godaddy"
|
GoDaddy models.Provider = "godaddy"
|
||||||
Google models.Provider = "google"
|
|
||||||
HE models.Provider = "he"
|
HE models.Provider = "he"
|
||||||
Hetzner models.Provider = "hetzner"
|
Hetzner models.Provider = "hetzner"
|
||||||
Infomaniak models.Provider = "infomaniak"
|
Infomaniak models.Provider = "infomaniak"
|
||||||
@@ -72,7 +71,6 @@ func ProviderChoices() []models.Provider {
|
|||||||
Gandi,
|
Gandi,
|
||||||
GCP,
|
GCP,
|
||||||
GoDaddy,
|
GoDaddy,
|
||||||
Google,
|
|
||||||
HE,
|
HE,
|
||||||
Hetzner,
|
Hetzner,
|
||||||
Infomaniak,
|
Infomaniak,
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ import (
|
|||||||
"github.com/qdm12/ddns-updater/internal/provider/providers/gandi"
|
"github.com/qdm12/ddns-updater/internal/provider/providers/gandi"
|
||||||
"github.com/qdm12/ddns-updater/internal/provider/providers/gcp"
|
"github.com/qdm12/ddns-updater/internal/provider/providers/gcp"
|
||||||
"github.com/qdm12/ddns-updater/internal/provider/providers/godaddy"
|
"github.com/qdm12/ddns-updater/internal/provider/providers/godaddy"
|
||||||
"github.com/qdm12/ddns-updater/internal/provider/providers/google"
|
|
||||||
"github.com/qdm12/ddns-updater/internal/provider/providers/he"
|
"github.com/qdm12/ddns-updater/internal/provider/providers/he"
|
||||||
"github.com/qdm12/ddns-updater/internal/provider/providers/hetzner"
|
"github.com/qdm12/ddns-updater/internal/provider/providers/hetzner"
|
||||||
"github.com/qdm12/ddns-updater/internal/provider/providers/infomaniak"
|
"github.com/qdm12/ddns-updater/internal/provider/providers/infomaniak"
|
||||||
@@ -116,8 +115,6 @@ func New(providerName models.Provider, data json.RawMessage, domain, host string
|
|||||||
return gcp.New(data, domain, host, ipVersion)
|
return gcp.New(data, domain, host, ipVersion)
|
||||||
case constants.GoDaddy:
|
case constants.GoDaddy:
|
||||||
return godaddy.New(data, domain, host, ipVersion)
|
return godaddy.New(data, domain, host, ipVersion)
|
||||||
case constants.Google:
|
|
||||||
return google.New(data, domain, host, ipVersion)
|
|
||||||
case constants.HE:
|
case constants.HE:
|
||||||
return he.New(data, domain, host, ipVersion)
|
return he.New(data, domain, host, ipVersion)
|
||||||
case constants.Hetzner:
|
case constants.Hetzner:
|
||||||
|
|||||||
@@ -1,171 +0,0 @@
|
|||||||
package google
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"net/http"
|
|
||||||
"net/netip"
|
|
||||||
"net/url"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/qdm12/ddns-updater/internal/models"
|
|
||||||
"github.com/qdm12/ddns-updater/internal/provider/constants"
|
|
||||||
"github.com/qdm12/ddns-updater/internal/provider/errors"
|
|
||||||
"github.com/qdm12/ddns-updater/internal/provider/headers"
|
|
||||||
"github.com/qdm12/ddns-updater/internal/provider/utils"
|
|
||||||
"github.com/qdm12/ddns-updater/pkg/ipextract"
|
|
||||||
"github.com/qdm12/ddns-updater/pkg/publicip/ipversion"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Provider struct {
|
|
||||||
domain string
|
|
||||||
host string
|
|
||||||
ipVersion ipversion.IPVersion
|
|
||||||
username string
|
|
||||||
password string
|
|
||||||
useProviderIP bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(data json.RawMessage, domain, host string,
|
|
||||||
ipVersion ipversion.IPVersion) (p *Provider, err error) {
|
|
||||||
extraSettings := struct {
|
|
||||||
Username string `json:"username"`
|
|
||||||
Password string `json:"password"`
|
|
||||||
UseProviderIP bool `json:"provider_ip"`
|
|
||||||
}{}
|
|
||||||
err = json.Unmarshal(data, &extraSettings)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
p = &Provider{
|
|
||||||
domain: domain,
|
|
||||||
host: host,
|
|
||||||
ipVersion: ipVersion,
|
|
||||||
username: extraSettings.Username,
|
|
||||||
password: extraSettings.Password,
|
|
||||||
useProviderIP: extraSettings.UseProviderIP,
|
|
||||||
}
|
|
||||||
err = p.isValid()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return p, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Provider) isValid() error {
|
|
||||||
switch {
|
|
||||||
case p.username == "":
|
|
||||||
return fmt.Errorf("%w", errors.ErrUsernameNotSet)
|
|
||||||
case p.password == "":
|
|
||||||
return fmt.Errorf("%w", errors.ErrPasswordNotSet)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Provider) String() string {
|
|
||||||
return utils.ToString(p.domain, p.host, constants.Google, p.ipVersion)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Provider) Domain() string {
|
|
||||||
return p.domain
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Provider) Host() string {
|
|
||||||
return p.host
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Provider) IPVersion() ipversion.IPVersion {
|
|
||||||
return p.ipVersion
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Provider) Proxied() bool {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Provider) BuildDomainName() string {
|
|
||||||
return utils.BuildDomainName(p.host, p.domain)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Provider) HTML() models.HTMLRow {
|
|
||||||
return models.HTMLRow{
|
|
||||||
Domain: fmt.Sprintf("<a href=\"http://%s\">%s</a>", p.BuildDomainName(), p.BuildDomainName()),
|
|
||||||
Host: p.Host(),
|
|
||||||
Provider: "<a href=\"https://domains.google.com/m/registrar\">Google</a>",
|
|
||||||
IPVersion: p.ipVersion.String(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Provider) Update(ctx context.Context, client *http.Client, ip netip.Addr) (newIP netip.Addr, err error) {
|
|
||||||
u := url.URL{
|
|
||||||
Scheme: "https",
|
|
||||||
Host: "domains.google.com",
|
|
||||||
Path: "/nic/update",
|
|
||||||
User: url.UserPassword(p.username, p.password),
|
|
||||||
}
|
|
||||||
values := url.Values{}
|
|
||||||
fqdn := utils.BuildURLQueryHostname(p.host, p.domain)
|
|
||||||
values.Set("hostname", fqdn)
|
|
||||||
if !p.useProviderIP {
|
|
||||||
values.Set("myip", ip.String())
|
|
||||||
}
|
|
||||||
u.RawQuery = values.Encode()
|
|
||||||
|
|
||||||
request, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil)
|
|
||||||
if err != nil {
|
|
||||||
return netip.Addr{}, fmt.Errorf("creating http request: %w", err)
|
|
||||||
}
|
|
||||||
headers.SetUserAgent(request)
|
|
||||||
|
|
||||||
response, err := client.Do(request)
|
|
||||||
if err != nil {
|
|
||||||
return netip.Addr{}, fmt.Errorf("doing http request: %w", err)
|
|
||||||
}
|
|
||||||
defer response.Body.Close()
|
|
||||||
|
|
||||||
b, err := io.ReadAll(response.Body)
|
|
||||||
if err != nil {
|
|
||||||
return netip.Addr{}, fmt.Errorf("reading response body: %w", err)
|
|
||||||
}
|
|
||||||
s := string(b)
|
|
||||||
|
|
||||||
switch s {
|
|
||||||
case "":
|
|
||||||
return netip.Addr{}, fmt.Errorf("%w: %d: %s", errors.ErrHTTPStatusNotValid, response.StatusCode, s)
|
|
||||||
case constants.Nohost, constants.Notfqdn:
|
|
||||||
return netip.Addr{}, fmt.Errorf("%w", errors.ErrHostnameNotExists)
|
|
||||||
case constants.Badauth:
|
|
||||||
return netip.Addr{}, fmt.Errorf("%w", errors.ErrAuth)
|
|
||||||
case constants.Badagent:
|
|
||||||
return netip.Addr{}, fmt.Errorf("%w", errors.ErrBannedUserAgent)
|
|
||||||
case constants.Abuse:
|
|
||||||
return netip.Addr{}, fmt.Errorf("%w", errors.ErrBannedAbuse)
|
|
||||||
case constants.Nineoneone:
|
|
||||||
return netip.Addr{}, fmt.Errorf("%w", errors.ErrDNSServerSide)
|
|
||||||
case "conflict constants.A", "conflict constants.AAAA":
|
|
||||||
return netip.Addr{}, fmt.Errorf("%w", errors.ErrConflictingRecord)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !strings.Contains(s, "nochg") && !strings.Contains(s, "good") {
|
|
||||||
return netip.Addr{}, fmt.Errorf("%w: %s", errors.ErrUnknownResponse, s)
|
|
||||||
}
|
|
||||||
|
|
||||||
var ips []netip.Addr
|
|
||||||
if ip.Is4() {
|
|
||||||
ips = ipextract.IPv4(s)
|
|
||||||
} else {
|
|
||||||
ips = ipextract.IPv6(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(ips) == 0 {
|
|
||||||
return netip.Addr{}, fmt.Errorf("%w", errors.ErrReceivedNoIP)
|
|
||||||
}
|
|
||||||
|
|
||||||
newIP = ips[0]
|
|
||||||
if !p.useProviderIP && ip.Compare(newIP) != 0 {
|
|
||||||
return netip.Addr{}, fmt.Errorf("%w: sent ip %s to update but received %s",
|
|
||||||
errors.ErrIPReceivedMismatch, ip, newIP)
|
|
||||||
}
|
|
||||||
return newIP, nil
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user