-
-
Notifications
You must be signed in to change notification settings - Fork 1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add DNS provider for VK Cloud (#1706)
Co-authored-by: Fernandez Ludovic <ldez@users.noreply.github.com>
- Loading branch information
1 parent
d99c75a
commit 8fe27e0
Showing
11 changed files
with
784 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
[run] | ||
timeout = "5m" | ||
timeout = "7m" | ||
skip-files = [] | ||
|
||
[linters-settings] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
--- | ||
title: "VK Cloud" | ||
date: 2019-03-03T16:39:46+01:00 | ||
draft: false | ||
slug: vkcloud | ||
dnsprovider: | ||
since: "v4.9.0" | ||
code: "vkcloud" | ||
url: "https://mcs.mail.ru/" | ||
--- | ||
|
||
<!-- THIS DOCUMENTATION IS AUTO-GENERATED. PLEASE DO NOT EDIT. --> | ||
<!-- providers/dns/vkcloud/vkcloud.toml --> | ||
<!-- THIS DOCUMENTATION IS AUTO-GENERATED. PLEASE DO NOT EDIT. --> | ||
|
||
|
||
Configuration for [VK Cloud](https://mcs.mail.ru/). | ||
|
||
|
||
<!--more--> | ||
|
||
- Code: `vkcloud` | ||
- Since: v4.9.0 | ||
|
||
|
||
Here is an example bash command using the VK Cloud provider: | ||
|
||
```bash | ||
VK_CLOUD_PROJECT_ID="<your_project_id>" \ | ||
VK_CLOUD_USERNAME="<your_email>" \ | ||
VK_CLOUD_PASSWORD="<your_password>" \ | ||
lego --email you@example.com --dns vkcloud --domains "example.org" --domains "*.example.org" run | ||
``` | ||
|
||
|
||
|
||
|
||
## Credentials | ||
|
||
| Environment Variable Name | Description | | ||
|-----------------------|-------------| | ||
| `VK_CLOUD_PASSWORD` | Password for VK Cloud account | | ||
| `VK_CLOUD_PROJECT_ID` | String ID of project in VK Cloud | | ||
| `VK_CLOUD_USERNAME` | Email of VK Cloud account | | ||
|
||
The environment variable names can be suffixed by `_FILE` to reference a file instead of a value. | ||
More information [here]({{< ref "dns#configuration-and-credentials" >}}). | ||
|
||
|
||
## Additional Configuration | ||
|
||
| Environment Variable Name | Description | | ||
|--------------------------------|-------------| | ||
| `VK_CLOUD_DNS_ENDPOINT` | URL of DNS API. Defaults to https://mcs.mail.ru/public-dns but can be changed for usage with private clouds | | ||
| `VK_CLOUD_DOMAIN_NAME` | Openstack users domain name. Defaults to `users` but can be changed for usage with private clouds | | ||
| `VK_CLOUD_IDENTITY_ENDPOINT` | URL of OpenStack Auth API, Defaults to https://infra.mail.ru:35357/v3/ but can be changed for usage with private clouds | | ||
| `VK_CLOUD_POLLING_INTERVAL` | Time between DNS propagation check | | ||
| `VK_CLOUD_PROPAGATION_TIMEOUT` | Maximum waiting time for DNS propagation | | ||
| `VK_CLOUD_TTL` | The TTL of the TXT record used for the DNS challenge | | ||
|
||
The environment variable names can be suffixed by `_FILE` to reference a file instead of a value. | ||
More information [here]({{< ref "dns#configuration-and-credentials" >}}). | ||
|
||
## Credential inforamtion | ||
|
||
You can find all required and additional information on ["Project/Keys" page](https://mcs.mail.ru/app/en/project/keys) of your cloud. | ||
|
||
| ENV Variable | Parameter from page | | ||
|----------------------------|---------------------| | ||
| VK_CLOUD_PROJECT_ID | Project ID | | ||
| VK_CLOUD_USERNAME | Username | | ||
| VK_CLOUD_DOMAIN_NAME | User Domain Name | | ||
| VK_CLOUD_IDENTITY_ENDPOINT | Identity endpoint | | ||
|
||
|
||
|
||
## More information | ||
|
||
- [API documentation](https://mcs.mail.ru/docs/networks/vnet/networks/publicdns/api) | ||
|
||
<!-- THIS DOCUMENTATION IS AUTO-GENERATED. PLEASE DO NOT EDIT. --> | ||
<!-- providers/dns/vkcloud/vkcloud.toml --> | ||
<!-- THIS DOCUMENTATION IS AUTO-GENERATED. PLEASE DO NOT EDIT. --> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
package internal | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"net/http" | ||
"net/url" | ||
"path" | ||
"strings" | ||
|
||
"github.com/gophercloud/gophercloud" | ||
"github.com/gophercloud/gophercloud/openstack" | ||
) | ||
|
||
// Client VK client. | ||
type Client struct { | ||
baseURL *url.URL | ||
openstack *gophercloud.ProviderClient | ||
authOpts gophercloud.AuthOptions | ||
authenticated bool | ||
} | ||
|
||
// NewClient creates a Client. | ||
func NewClient(endpoint string, authOpts gophercloud.AuthOptions) (*Client, error) { | ||
err := validateAuthOptions(authOpts) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
openstackClient, err := openstack.NewClient(authOpts.IdentityEndpoint) | ||
if err != nil { | ||
return nil, fmt.Errorf("new client: %w", err) | ||
} | ||
|
||
baseURL, err := url.Parse(endpoint) | ||
if err != nil { | ||
return nil, fmt.Errorf("parse URL: %w", err) | ||
} | ||
|
||
return &Client{ | ||
baseURL: baseURL, | ||
openstack: openstackClient, | ||
authOpts: authOpts, | ||
}, nil | ||
} | ||
|
||
func (c *Client) ListZones() ([]DNSZone, error) { | ||
var zones []DNSZone | ||
opts := &gophercloud.RequestOpts{JSONResponse: &zones} | ||
|
||
// TODO(ldez): go1.19 => c.baseURL.JoinPath("/") | ||
endpoint := joinPath(c.baseURL, "/") | ||
|
||
err := c.request(http.MethodGet, endpoint, opts) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return zones, nil | ||
} | ||
|
||
func (c *Client) ListTXTRecords(zoneUUID string) ([]DNSTXTRecord, error) { | ||
var records []DNSTXTRecord | ||
opts := &gophercloud.RequestOpts{JSONResponse: &records} | ||
|
||
// TODO(ldez): go1.19 => c.baseURL.JoinPath(zoneUUID, "txt", "/") | ||
endpoint := joinPath(c.baseURL, zoneUUID, "txt", "/") | ||
|
||
err := c.request(http.MethodGet, endpoint, opts) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return records, nil | ||
} | ||
|
||
func (c *Client) CreateTXTRecord(zoneUUID string, record *DNSTXTRecord) error { | ||
opts := &gophercloud.RequestOpts{ | ||
JSONBody: record, | ||
JSONResponse: record, | ||
} | ||
|
||
// TODO(ldez): go1.19 => c.baseURL.JoinPath(zoneUUID, "txt", "/") | ||
endpoint := joinPath(c.baseURL, zoneUUID, "txt", "/") | ||
|
||
return c.request(http.MethodPost, endpoint, opts) | ||
} | ||
|
||
func (c *Client) DeleteTXTRecord(zoneUUID, recordUUID string) error { | ||
// TODO(ldez): go1.19 => c.baseURL.JoinPath(zoneUUID, "txt", recordUUID) | ||
endpoint := joinPath(c.baseURL, zoneUUID, "txt", recordUUID) | ||
|
||
return c.request(http.MethodDelete, endpoint, &gophercloud.RequestOpts{}) | ||
} | ||
|
||
func (c *Client) request(method string, endpoint *url.URL, options *gophercloud.RequestOpts) error { | ||
if err := c.lazyAuth(); err != nil { | ||
return fmt.Errorf("auth: %w", err) | ||
} | ||
|
||
_, err := c.openstack.Request(method, endpoint.String(), options) | ||
if err != nil { | ||
return fmt.Errorf("request: %w", err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (c *Client) lazyAuth() error { | ||
if c.authenticated { | ||
return nil | ||
} | ||
|
||
err := openstack.Authenticate(c.openstack, c.authOpts) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
c.authenticated = true | ||
|
||
return nil | ||
} | ||
|
||
func validateAuthOptions(opts gophercloud.AuthOptions) error { | ||
if opts.TenantID == "" { | ||
return errors.New("project id is missing in credentials information") | ||
} | ||
|
||
if opts.Username == "" { | ||
return errors.New("username is missing in credentials information") | ||
} | ||
|
||
if opts.Password == "" { | ||
return errors.New("password is missing in credentials information") | ||
} | ||
|
||
if opts.IdentityEndpoint == "" { | ||
return errors.New("identity endpoint is missing in config") | ||
} | ||
|
||
if opts.DomainName == "" { | ||
return errors.New("domain name is missing in config") | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// light version of go1.19 url.URL.JoinPath. | ||
// TODO(ldez): must be remove when we will update to go1.19. | ||
func joinPath(uri *url.URL, elem ...string) *url.URL { | ||
result := path.Join(elem...) | ||
result = path.Join(uri.Path, result) | ||
if len(elem) > 0 && strings.HasSuffix(elem[len(elem)-1], "/") { | ||
result += "/" | ||
} | ||
|
||
parse, _ := uri.Parse(result) | ||
|
||
return parse | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package internal | ||
|
||
type DNSZone struct { | ||
UUID string `json:"uuid,omitempty"` | ||
Tenant string `json:"tenant,omitempty"` | ||
SoaPrimaryDNS string `json:"soa_primary_dns,omitempty"` | ||
SoaAdminEmail string `json:"soa_admin_email,omitempty"` | ||
SoaSerial int `json:"soa_serial,omitempty"` | ||
SoaRefresh int `json:"soa_refresh,omitempty"` | ||
SoaRetry int `json:"soa_retry,omitempty"` | ||
SoaExpire int `json:"soa_expire,omitempty"` | ||
SoaTTL int `json:"soa_ttl,omitempty"` | ||
Zone string `json:"zone,omitempty"` | ||
Status string `json:"status,omitempty"` | ||
} | ||
|
||
type DNSTXTRecord struct { | ||
UUID string `json:"uuid,omitempty"` | ||
Name string `json:"name,omitempty"` | ||
DNS string `json:"dns,omitempty"` | ||
Content string `json:"content,omitempty"` | ||
TTL int `json:"ttl,omitempty"` | ||
} |
Oops, something went wrong.