Skip to content

Commit

Permalink
added support for requesting extensions and new client APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
lanrat committed Jun 30, 2022
1 parent c492ad1 commit 4bef20e
Show file tree
Hide file tree
Showing 4 changed files with 166 additions and 60 deletions.
29 changes: 27 additions & 2 deletions cmd/czds-request/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ var (
requestTLDs = flag.String("request", "", "comma separated list of zones to request")
requestAll = flag.Bool("request-all", false, "request all available zones")
status = flag.Bool("status", false, "print status of zones")
extendTLDs = flag.String("extend", "", "comma separated list of zones to request extensions")
extendAll = flag.Bool("extend-all", false, "extend all possible zones")

client *czds.Client
)
Expand Down Expand Up @@ -51,7 +53,8 @@ func main() {
checkFlags()

doRequest := (*requestAll || len(*requestTLDs) > 0)
if !*printTerms && !*status && !doRequest {
doExtend := (*extendAll || len(*extendTLDs) > 0)
if !*printTerms && !*status && !(doRequest || doExtend) {
log.Fatal("Nothing to do!")
}

Expand Down Expand Up @@ -93,7 +96,7 @@ func main() {
}
var requestedTLDs []string
if *requestAll {
v("Requesting All TLDs")
v("Requesting all TLDs")
requestedTLDs, err = client.RequestAllTLDs(*reason)
} else {
tlds := strings.Split(*requestTLDs, ",")
Expand All @@ -109,6 +112,28 @@ func main() {
fmt.Printf("Requested: %v\n", requestedTLDs)
}
}
// extend
if doExtend {
var extendedTLDs []string
if *extendAll {
v("Requesting extension for all TLDs")
extendedTLDs, err = client.ExtendAllTLDs()
} else {
tlds := strings.Split(*extendTLDs, ",")
for _, tld := range tlds {
v("Requesting extension %v", tld)
err = client.ExtendTLD(tld)
extendedTLDs = tlds
}
}

if err != nil {
log.Fatal(err)
}
if len(extendedTLDs) > 0 {
fmt.Printf("Extended: %v\n", extendedTLDs)
}
}
}

func printTLDStatus(tldStatus czds.TLDStatus) {
Expand Down
64 changes: 11 additions & 53 deletions cmd/czds-status/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"fmt"
"log"
"os"
"strings"
"time"

"github.com/lanrat/czds"
Expand All @@ -18,15 +17,11 @@ var (
verbose = flag.Bool("verbose", false, "enable verbose logging")
id = flag.String("id", "", "ID of specific zone request to lookup, defaults to printing all")
zone = flag.String("zone", "", "same as -id, but prints the request by zone name")
cancel = flag.Bool("cancel", false, "cancel the request. Requires -id or -zone")
cancel = flag.Bool("cancel", false, "cancel the request. Requires -id or -zone") // TODO move this to czds-request

client *czds.Client
)

const (
pageSize = 100
)

func v(format string, v ...interface{}) {
if *verbose {
log.Printf(format, v...)
Expand Down Expand Up @@ -64,7 +59,7 @@ func main() {

if *zone != "" {
// get id from zone name
zoneID, err := getZoneRequestID(*zone)
zoneID, err := client.GetZoneRequestID(*zone)
if err != nil {
log.Fatal(err)
}
Expand Down Expand Up @@ -108,36 +103,17 @@ func cancelRequest(id, zone string) {
printRequestInfo(info)
}

func getZoneRequestID(zone string) (string, error) {
filter := czds.RequestsFilter{
Status: czds.RequestAll,
Filter: strings.ToLower(zone),
Pagination: czds.RequestsPagination{
Size: 1,
Page: 0,
},
Sort: czds.RequestsSort{
Field: czds.SortByLastUpdated,
Direction: czds.SortDesc,
},
}
requests, err := client.GetRequests(&filter)
if err != nil {
return "", err
}
if requests.TotalRequests == 0 {
return "", fmt.Errorf("no request found for zone %s", zone)
}
return requests.Requests[0].RequestID, nil
}

func printRequestInfo(info *czds.RequestsInfo) {
fmt.Printf("ID:\t%s\n", info.RequestID)
fmt.Printf("TLD:\t%s (%s)\n", info.TLD.TLD, info.TLD.ULabel)
fmt.Printf("Status:\t%s\n", info.Status)
fmt.Printf("Created:\t%s\n", info.Created.Format(time.ANSIC))
fmt.Printf("Updated:\t%s\n", info.LastUpdated.Format(time.ANSIC))
fmt.Printf("Expires:\t%s\n", expiredTime(info.Expired))
fmt.Printf("AutoRenew:\t%t\n", info.AutoRenew)
fmt.Printf("Extensible:\t%t\n", info.Extensible)
fmt.Printf("ExtensionInProcess:\t%t\n", info.ExtensionInProcess)
fmt.Printf("Cancellable:\t%t\n", info.Cancellable)
fmt.Printf("Request IP:\t%s\n", info.RequestIP)
fmt.Println("FTP IPs:\t", info.FtpIps)
fmt.Printf("Reason:\t%s\n", info.Reason)
Expand All @@ -148,37 +124,19 @@ func printRequestInfo(info *czds.RequestsInfo) {
}

func listAll() {
filter := czds.RequestsFilter{
Status: czds.RequestAll,
Filter: "",
Pagination: czds.RequestsPagination{
Size: pageSize,
Page: 0,
},
Sort: czds.RequestsSort{
Field: czds.SortByCreated,
Direction: czds.SortDesc,
},
}

requests, err := client.GetRequests(&filter)
requests, err := client.GetAllRequests(czds.RequestAll)
if err != nil {
log.Fatal(err)
}

v("Total requests: %d", requests.TotalRequests)
if len(requests.Requests) > 0 {
v("Total requests: %d", len(requests))
if len(requests) > 0 {
printHeader()
}
for len(requests.Requests) != 0 {
for _, request := range requests.Requests {
for len(requests) != 0 {
for _, request := range requests {
printRequest(request)
}
filter.Pagination.Page++
requests, err = client.GetRequests(&filter)
if err != nil {
log.Fatal(err)
}
}
}

Expand Down
73 changes: 68 additions & 5 deletions czds.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"fmt"
"io"
"net/http"
"strings"
"sync"
"time"

Expand Down Expand Up @@ -159,12 +160,15 @@ func (c *Client) jsonRequest(auth bool, method, url string, request, response in
// got an error, decode it
if resp.StatusCode != http.StatusOK {
var errorResp errorResponse
err := fmt.Errorf("error on request %s, got Status %s %s", url, resp.Status, http.StatusText(resp.StatusCode))
jsonError := json.NewDecoder(resp.Body).Decode(&errorResp)
if jsonError != nil {
return fmt.Errorf("error decoding json %w on errord request: %s", jsonError, err.Error())
err := fmt.Errorf("error on request %q: got Status %s %s", url, resp.Status, http.StatusText(resp.StatusCode))
if resp.ContentLength != 0 {
jsonError := json.NewDecoder(resp.Body).Decode(&errorResp)
if jsonError != nil {
return fmt.Errorf("error decoding json %w on errord request: %s", jsonError, err.Error())
}
err = fmt.Errorf("%w HTTPStatus: %d Message: %q", err, errorResp.HTTPStatus, errorResp.Message)
}
return fmt.Errorf("%w, HTTPStatus: %d Message: %q", err, errorResp.HTTPStatus, errorResp.Message)
return err
}

if response != nil {
Expand Down Expand Up @@ -205,3 +209,62 @@ func (ar *authResponse) getExpiration() (time.Time, error) {
exp := time.Unix(token.Data.Exp, 0)
return exp, err
}

// GetZoneRequestID returns the most request RequestID for the given zone
func (c *Client) GetZoneRequestID(zone string) (string, error) {
filter := RequestsFilter{
Status: RequestAll,
Filter: strings.ToLower(zone),
Pagination: RequestsPagination{
Size: 1,
Page: 0,
},
Sort: RequestsSort{
Field: SortByLastUpdated,
Direction: SortDesc,
},
}
requests, err := c.GetRequests(&filter)
if err != nil {
return "", err
}
if requests.TotalRequests == 0 {
return "", fmt.Errorf("no request found for zone %s", zone)
}
return requests.Requests[0].RequestID, nil
}

// GetAllRequests returns the request information for all requests with the given status
// status should be one of the constsnt czds.Status* strings
func (c *Client) GetAllRequests(status string) ([]Request, error) {
const pageSize = 100
filter := RequestsFilter{
Status: status,
Filter: "",
Pagination: RequestsPagination{
Size: pageSize,
Page: 0,
},
Sort: RequestsSort{
Field: SortByCreated,
Direction: SortDesc,
},
}

out := make([]Request, 0, 100)
requests, err := c.GetRequests(&filter)
if err != nil {
return out, err
}

for len(requests.Requests) != 0 {
out = append(out, requests.Requests...)
filter.Pagination.Page++
requests, err = c.GetRequests(&filter)
if err != nil {
return out, err
}
}

return out, nil
}
60 changes: 60 additions & 0 deletions requests.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package czds

import (
"encoding/json"
"fmt"
"io"
"time"
Expand Down Expand Up @@ -46,6 +47,9 @@ const (
StatusRevoked = "revoked" // unverified
)

// used in RequestExtension
var emptyStruct, _ = json.Marshal(make(map[int]int))

// RequestsFilter is used to set what results should be returned by GetRequests
type RequestsFilter struct {
Status string `json:"status"` // should be set to one of the Request* constants
Expand Down Expand Up @@ -196,6 +200,14 @@ func (c *Client) CancelRequest(cancel *CancelRequestSubmission) (*RequestsInfo,
return request, err
}

// RequestExtension submits a request to have the access extended.
// Can only request extensions for requests expiering within 30 days.
func (c *Client) RequestExtension(requestID string) (*RequestsInfo, error) {
request := new(RequestsInfo)
err := c.jsonAPI("POST", "/czds/requests/extension/"+requestID, emptyStruct, request)
return request, err
}

// DownloadAllRequests outputs the contents of the csv file downloaded by
// the "Download All Requests" button on the CZDS portal to the provided output
func (c *Client) DownloadAllRequests(output io.Writer) error {
Expand Down Expand Up @@ -272,3 +284,51 @@ func (c *Client) RequestAllTLDs(reason string) ([]string, error) {
err = c.SubmitRequest(request)
return requestTLDs, err
}

// ExtendTLD is a helper function that requests extensions to the provided tld
// TLDs provided should be marked as Extensible from GetRequestInfo()
func (c *Client) ExtendTLD(tld string) error {

zoneID, err := c.GetZoneRequestID(tld)
if err != nil {
return fmt.Errorf("error GetZoneRequestID(%q): %w", tld, err)
}

info, err := c.RequestExtension(zoneID)
if err != nil {
return fmt.Errorf("RequestExtension(%q): %w", tld, err)
}

if !info.ExtensionInProcess {
return fmt.Errorf("error, zone request %q, %q: extension already in progress", tld, zoneID)
}

return nil
}

// ExtendAllTLDs is a helper function to request extensions to all TLDs that are extendable
func (c *Client) ExtendAllTLDs() ([]string, error) {
tlds := make([]string, 0, 10)

requests, err := c.GetAllRequests(RequestApproved)
if err != nil {
return tlds, err
}

// get available to extend
for _, r := range requests {
info, err := c.GetRequestInfo(r.RequestID)
if err != nil {
return nil, err
}
if info.Extensible {
_, err := c.RequestExtension(info.RequestID)
if err != nil {
return tlds, err
}
tlds = append(tlds, info.TLD.TLD)
}
}

return tlds, err
}

0 comments on commit 4bef20e

Please sign in to comment.