Skip to content

Commit

Permalink
Change HTTP methods from GET to POST due to public IP change (#17)
Browse files Browse the repository at this point in the history
Co-authored-by: Iutkin Egorh <[email protected]>
  • Loading branch information
IutkinEgor and Iutkin Egorh authored Dec 20, 2024
1 parent d6c6c57 commit 7bae5ee
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 57 deletions.
17 changes: 12 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,18 @@ This solver allows you to use cert-manager with the Regru API. Documentation on

### Preparation

You must check access to the Regru API from your IP(s). You should use this command:

```shell
curl "https://api.reg.ru/api/regru2/zone/get_resource_records?input_data=%7B%22username%22%3A%22USER_NAME%22%2C%22password%22%3A%22PASSWORD_STRING%22%2C%22domains%22%3A%5B%7B%22dname%22%3A%22ZONE_NAME%22%7D%5D%2C%22output_content_type%22%3A%22plain%22%7D&input_format=json"

You must check access to the Regru API from your IP(s). You should do POST request with ContentType `multipart/form-data;`:

```http
POST "https://www.reg.ru/api/regru2/zone/get_resource_records"
input_format: json
output_format: json
io_encoding: utf8
input_data: {"domains":[{"dname":"ZONE_NAME"}],"password":"PASSWORD","username":"USER_NAME"}
show_input_params: 0
username: USER_NAME
password: PASSWORD
```
where `USER_NAME` and `PASSWORD_STRING` are your credentials to access the Regru API, and `ZONE_NAME` is your domain.

Expand Down
106 changes: 54 additions & 52 deletions client.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package main

import (
"errors"
"bytes"
"encoding/json"
"fmt"
"io"
"mime/multipart"
"net/http"
url2 "net/url"
)

const (
Expand All @@ -27,73 +28,74 @@ func NewRegruClient(username string, password string, zone string) *RegruClient
}

func (c *RegruClient) getRecords() error {
s := fmt.Sprintf("{\"username\":\"%s\",\"password\":\"%s\",\"domains\":[{\"dname\":\"%s\"}],\"output_content_type\":\"plain\"}", c.username, c.password, c.zone)
url := fmt.Sprintf("%szone/get_resource_records?input_data=%s&input_format=json", defaultBaseURL, url2.QueryEscape(s))

fmt.Println("Get TXT Query:", url)
res, err := http.Get(url)
if err != nil {
return fmt.Errorf("failed to make GET request: %v", err)
}

body, err := io.ReadAll(res.Body)
res.Body.Close()
if res.StatusCode > 299 {
return errors.New(fmt.Sprintf("response failed with status code: %d and body: %s", res.StatusCode, body))
}
if err != nil {
return fmt.Errorf("failed to ready response")
}

fmt.Printf("Get TXT success. Response body: %s", body)

return nil
apiURL := fmt.Sprintf("%szone/get_resource_records", defaultBaseURL)
inputData := fmt.Sprintf("{\"domains\":[{\"dname\":\"%s\"}],\"password\":\"%s\",\"username\":\"%s\"}", c.zone, c.password, c.username)
return sendPOST(apiURL, inputData, *c)
}

func (c *RegruClient) createTXT(domain string, value string) error {
s := fmt.Sprintf("{\"username\":\"%s\",\"password\":\"%s\",\"domains\":[{\"dname\":\"%s\"}],\"subdomain\":\"%s\",\"text\":\"%s\",\"output_content_type\":\"plain\"}", c.username, c.password, c.zone, domain, value)
url := fmt.Sprintf("%szone/add_txt?input_data=%s&input_format=json", defaultBaseURL, url2.QueryEscape(s))
apiURL := fmt.Sprintf("%szone/add_txt", defaultBaseURL)
inputData := fmt.Sprintf("{\"domains\":[{\"dname\":\"%s\"}],\"password\":\"%s\",\"subdomain\":\"%s\",\"text\":\"%s\",\"username\":\"%s\"}", c.zone, c.password, domain, value, c.username)
return sendPOST(apiURL, inputData, *c)
}

fmt.Println("Create TXT Query:", url)
res, err := http.Get(url)
func (c *RegruClient) deleteTXT(domain string, value string) error {
apiURL := fmt.Sprintf("%szone/remove_record", defaultBaseURL)
inputData := fmt.Sprintf("{\"content\":\"%s\",\"domains\":[{\"dname\":\"%s\"}],\"password\":\"%s\",\"record_type\":\"TXT\",\"subdomain\":\"%s\",\"username\":\"%s\"}", value, c.zone, c.password, domain, c.username)
return sendPOST(apiURL, inputData, *c)
}

func sendPOST(apiURL string, inputData string, c RegruClient) error {
var b bytes.Buffer
writer := multipart.NewWriter(&b)

writer.WriteField("input_format", "json")
writer.WriteField("output_format", "json")
writer.WriteField("io_encoding", "utf8")
writer.WriteField("input_data", inputData)
writer.WriteField("show_input_params", "0")
writer.WriteField("username", c.username)
writer.WriteField("password", c.password)
writer.Close()

// Perform the POST request
req, err := http.NewRequest("POST", apiURL, &b)
if err != nil {
return fmt.Errorf("failed to make GET request: %v", err)
return fmt.Errorf("failed to create request: %v", err)
}
req.Header.Set("Content-Type", writer.FormDataContentType())

body, err := io.ReadAll(res.Body)
res.Body.Close()
if res.StatusCode > 299 {
return errors.New(fmt.Sprintf("response failed with status code: %d and body: %s", res.StatusCode, body))
}
// Perform the POST request
res, err := http.DefaultClient.Do(req)
if err != nil {
return fmt.Errorf("failed to ready response")
return fmt.Errorf("failed to make POST request: %v", err)
}
defer res.Body.Close()

fmt.Printf("Create TXT success. Response body: %s", body)

return nil
}

func (c *RegruClient) deleteTXT(domain string, value string) error {
s := fmt.Sprintf("{\"username\":\"%s\",\"password\":\"%s\",\"domains\":[{\"dname\":\"%s\"}],\"subdomain\":\"%s\",\"content\":\"%s\",\"record_type\":\"TXT\",\"output_content_type\":\"plain\"}", c.username, c.password, c.zone, domain, value)
url := fmt.Sprintf("%szone/remove_record?input_data=%s&input_format=json", defaultBaseURL, url2.QueryEscape(s))

fmt.Println("Delete TXT Query:", url)
res, err := http.Get(url)
// Check for non-success status code
if res.StatusCode != http.StatusOK {
body, _ := io.ReadAll(res.Body) // Ignore error for brevity
return fmt.Errorf("response failed with status code: %d and body: %s", res.StatusCode, body)
}

// Read and output the response body
body, err := io.ReadAll(res.Body)
if err != nil {
return fmt.Errorf("failed to make GET request: %v", err)
return fmt.Errorf("failed to read response body: %v", err)
}

body, err := io.ReadAll(res.Body)
res.Body.Close()
if res.StatusCode > 299 {
return errors.New(fmt.Sprintf("response failed with status code: %d and body: %s", res.StatusCode, body))
// Print the response body as formatted JSON
var jsonResponse interface{}
if err := json.Unmarshal(body, &jsonResponse); err != nil {
return fmt.Errorf("failed to unmarshal response body: %v", err)
}

// Marshal the jsonResponse with indentation for pretty printing
prettyJSON, err := json.MarshalIndent(jsonResponse, "", " ")
if err != nil {
return fmt.Errorf("failed to ready response")
return fmt.Errorf("failed to marshal JSON: %v", err)
}

fmt.Printf("Delete TXT success. Response body: %s", body)
fmt.Printf("Response body: %s\n", prettyJSON)
return nil
}

0 comments on commit 7bae5ee

Please sign in to comment.