Skip to content

Commit 85a5e83

Browse files
committed
added Support for inwx
1 parent 3a3c892 commit 85a5e83

File tree

5 files changed

+179
-0
lines changed

5 files changed

+179
-0
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ Light container updating DNS A and/or AAAA records periodically for multiple DNS
5252
- Google
5353
- He.net
5454
- Infomaniak
55+
- INWX
5556
- Linode
5657
- LuaDNS
5758
- Namecheap
@@ -175,6 +176,7 @@ Check the documentation for your DNS provider:
175176
- [Google](https://github.com/qdm12/ddns-updater/blob/master/docs/google.md)
176177
- [He.net](https://github.com/qdm12/ddns-updater/blob/master/docs/he.net.md)
177178
- [Infomaniak](https://github.com/qdm12/ddns-updater/blob/master/docs/infomaniak.md)
179+
- [INWX](https://github.com/qdm12/ddns-updater/blob/master/docs/inwx.md)
178180
- [Linode](https://github.com/qdm12/ddns-updater/blob/master/docs/linode.md)
179181
- [LuaDNS](https://github.com/qdm12/ddns-updater/blob/master/docs/luadns.md)
180182
- [Namecheap](https://github.com/qdm12/ddns-updater/blob/master/docs/namecheap.md)

docs/inwx.md

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# OpenDNS
2+
3+
## Configuration
4+
5+
### Example
6+
7+
```json
8+
{
9+
"settings": [
10+
{
11+
"provider": "dyn",
12+
"domain": "domain.com",
13+
"host": "@",
14+
"username": "username",
15+
"password": "password",
16+
"ip_version": "ipv4",
17+
}
18+
]
19+
}
20+
```
21+
22+
### Compulsory parameters
23+
- `"domain"`
24+
- `"host"` is your host and can be a subdomain or `"@"`
25+
- `"username"`
26+
- `"password"`
27+
28+
### Optional parameters
29+
30+
- `"ip_version"` can be `ipv4` (A records) or `ipv6` (AAAA records), defaults to `ipv4 or ipv6`
31+
32+
## Domain setup

internal/settings/constants/providers.go

+2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const (
2525
Google models.Provider = "google"
2626
HE models.Provider = "he"
2727
Infomaniak models.Provider = "infomaniak"
28+
INWX models.Provider = "inwx"
2829
Linode models.Provider = "linode"
2930
LuaDNS models.Provider = "luadns"
3031
Namecheap models.Provider = "namecheap"
@@ -63,6 +64,7 @@ func ProviderChoices() []models.Provider {
6364
Google,
6465
HE,
6566
Infomaniak,
67+
INWX,
6668
Linode,
6769
LuaDNS,
6870
Namecheap,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
package inwx
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
"fmt"
7+
"io"
8+
"net"
9+
"net/http"
10+
"net/url"
11+
"strings"
12+
13+
"github.com/qdm12/ddns-updater/internal/models"
14+
"github.com/qdm12/ddns-updater/internal/settings/errors"
15+
"github.com/qdm12/ddns-updater/internal/settings/headers"
16+
"github.com/qdm12/ddns-updater/internal/settings/utils"
17+
"github.com/qdm12/ddns-updater/pkg/publicip/ipversion"
18+
)
19+
20+
type Provider struct {
21+
domain string
22+
host string
23+
ipVersion ipversion.IPVersion
24+
username string
25+
password string
26+
}
27+
28+
func New(data json.RawMessage, domain, host string,
29+
ipVersion ipversion.IPVersion) (p *Provider, err error) {
30+
extraSettings := struct {
31+
Username string `json:"username"`
32+
Password string `json:"password"`
33+
}{}
34+
if err := json.Unmarshal(data, &extraSettings); err != nil {
35+
return nil, err
36+
}
37+
p = &Provider{
38+
domain: domain,
39+
host: host,
40+
ipVersion: ipVersion,
41+
username: extraSettings.Username,
42+
password: extraSettings.Password,
43+
}
44+
if err := p.isValid(); err != nil {
45+
return nil, err
46+
}
47+
return p, nil
48+
}
49+
50+
func (p *Provider) isValid() error {
51+
switch {
52+
case len(p.username) == 0:
53+
return errors.ErrEmptyUsername
54+
case len(p.password) == 0:
55+
return errors.ErrEmptyPassword
56+
case p.host == "*":
57+
return errors.ErrHostWildcard
58+
}
59+
return nil
60+
}
61+
62+
func (p *Provider) String() string {
63+
return fmt.Sprintf("[domain: %s | host: %s | provider: INWX]", p.domain, p.host)
64+
}
65+
66+
func (p *Provider) Domain() string {
67+
return p.domain
68+
}
69+
70+
func (p *Provider) Host() string {
71+
return p.host
72+
}
73+
74+
func (p *Provider) IPVersion() ipversion.IPVersion {
75+
return p.ipVersion
76+
}
77+
78+
func (p *Provider) Proxied() bool {
79+
return false
80+
}
81+
82+
func (p *Provider) BuildDomainName() string {
83+
return utils.BuildDomainName(p.host, p.domain)
84+
}
85+
86+
func (p *Provider) HTML() models.HTMLRow {
87+
return models.HTMLRow{
88+
Domain: models.HTML(fmt.Sprintf("<a href=\"http://%s\">%s</a>", p.BuildDomainName(), p.BuildDomainName())),
89+
Host: models.HTML(p.Host()),
90+
Provider: "<a href=\"https://inwx.com/\">INWX</a>",
91+
IPVersion: models.HTML(p.ipVersion.String()),
92+
}
93+
}
94+
95+
func (p *Provider) Update(ctx context.Context, client *http.Client, ip net.IP) (newIP net.IP, err error) {
96+
u := url.URL{
97+
Scheme: "https",
98+
User: url.UserPassword(p.username, p.password),
99+
Host: "dyndns.inwx.com",
100+
Path: "/nic/update",
101+
}
102+
values := url.Values{}
103+
values.Set("hostname", utils.BuildURLQueryHostname(p.host, p.domain))
104+
if ip.To4() != nil {
105+
values.Set("myip", ip.String())
106+
} else {
107+
values.Set("myipv6",ip.String())
108+
}
109+
110+
u.RawQuery = values.Encode()
111+
112+
request, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil)
113+
if err != nil {
114+
return nil, err
115+
}
116+
headers.SetUserAgent(request)
117+
118+
response, err := client.Do(request)
119+
if err != nil {
120+
return nil, err
121+
}
122+
defer response.Body.Close()
123+
124+
b, err := io.ReadAll(response.Body)
125+
if err != nil {
126+
return nil, fmt.Errorf("%w: %s", errors.ErrUnmarshalResponse, err)
127+
}
128+
s := string(b)
129+
130+
if response.StatusCode != http.StatusOK {
131+
return nil, fmt.Errorf("%w: %d: %s", errors.ErrBadHTTPStatus, response.StatusCode, s)
132+
}
133+
134+
if !strings.HasPrefix(s, "good") || !strings.HasPrefix(s,"nochg") {
135+
return nil, fmt.Errorf("%w: %s", errors.ErrUnknownResponse, s)
136+
}
137+
138+
139+
return ip, nil
140+
}

internal/settings/settings.go

+3
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232
"github.com/qdm12/ddns-updater/internal/settings/providers/google"
3333
"github.com/qdm12/ddns-updater/internal/settings/providers/he"
3434
"github.com/qdm12/ddns-updater/internal/settings/providers/infomaniak"
35+
"github.com/qdm12/ddns-updater/internal/settings/providers/inwx"
3536
"github.com/qdm12/ddns-updater/internal/settings/providers/linode"
3637
"github.com/qdm12/ddns-updater/internal/settings/providers/luadns"
3738
"github.com/qdm12/ddns-updater/internal/settings/providers/namecheap"
@@ -108,6 +109,8 @@ func New(provider models.Provider, data json.RawMessage, domain, host string, //
108109
return he.New(data, domain, host, ipVersion)
109110
case constants.Infomaniak:
110111
return infomaniak.New(data, domain, host, ipVersion)
112+
case constants.INWX:
113+
return inwx.New(data, domain, host, ipVersion)
111114
case constants.Linode:
112115
return linode.New(data, domain, host, ipVersion)
113116
case constants.LuaDNS:

0 commit comments

Comments
 (0)