mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2024-09-20 14:56:20 +08:00
7fd6a74e0c
Co-authored-by: Josh Zhang <jzhang1@stackoverflow.com>
344 lines
10 KiB
Go
344 lines
10 KiB
Go
package cloudflare
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/goccy/go-json"
|
|
)
|
|
|
|
// SizeOptions can be passed to a list request to configure size and cursor location.
|
|
// These values will be defaulted if omitted.
|
|
//
|
|
// This should be swapped to ResultInfoCursors once the types are corrected.
|
|
type SizeOptions struct {
|
|
Size int `json:"size,omitempty" url:"size,omitempty"`
|
|
Before *int `json:"before,omitempty" url:"before,omitempty"`
|
|
After *int `json:"after,omitempty" url:"after,omitempty"`
|
|
}
|
|
|
|
// PagesDeploymentStageLogs represents the logs for a Pages deployment stage.
|
|
type PagesDeploymentStageLogs struct {
|
|
Name string `json:"name"`
|
|
StartedOn *time.Time `json:"started_on"`
|
|
EndedOn *time.Time `json:"ended_on"`
|
|
Status string `json:"status"`
|
|
Start int `json:"start"`
|
|
End int `json:"end"`
|
|
Total int `json:"total"`
|
|
Data []PagesDeploymentStageLogEntry `json:"data"`
|
|
}
|
|
|
|
// PagesDeploymentStageLogEntry represents a single log entry in a Pages deployment stage.
|
|
type PagesDeploymentStageLogEntry struct {
|
|
ID int `json:"id"`
|
|
Timestamp *time.Time `json:"timestamp"`
|
|
Message string `json:"message"`
|
|
}
|
|
|
|
// PagesDeploymentLogs represents the logs for a Pages deployment.
|
|
type PagesDeploymentLogs struct {
|
|
Total int `json:"total"`
|
|
IncludesContainerLogs bool `json:"includes_container_logs"`
|
|
Data []PagesDeploymentLogEntry `json:"data"`
|
|
}
|
|
|
|
// PagesDeploymentLogEntry represents a single log entry in a Pages deployment.
|
|
type PagesDeploymentLogEntry struct {
|
|
Timestamp *time.Time `json:"ts"`
|
|
Line string `json:"line"`
|
|
}
|
|
|
|
type pagesDeploymentListResponse struct {
|
|
Response
|
|
Result []PagesProjectDeployment `json:"result"`
|
|
ResultInfo `json:"result_info"`
|
|
}
|
|
|
|
type pagesDeploymentResponse struct {
|
|
Response
|
|
Result PagesProjectDeployment `json:"result"`
|
|
}
|
|
|
|
type pagesDeploymentLogsResponse struct {
|
|
Response
|
|
Result PagesDeploymentLogs `json:"result"`
|
|
ResultInfo `json:"result_info"`
|
|
}
|
|
|
|
type ListPagesDeploymentsParams struct {
|
|
ProjectName string `url:"-"`
|
|
|
|
ResultInfo
|
|
}
|
|
|
|
type GetPagesDeploymentInfoParams struct {
|
|
ProjectName string
|
|
DeploymentID string
|
|
}
|
|
|
|
type GetPagesDeploymentStageLogsParams struct {
|
|
ProjectName string
|
|
DeploymentID string
|
|
StageName string
|
|
|
|
SizeOptions
|
|
}
|
|
|
|
type GetPagesDeploymentLogsParams struct {
|
|
ProjectName string
|
|
DeploymentID string
|
|
|
|
SizeOptions
|
|
}
|
|
|
|
type DeletePagesDeploymentParams struct {
|
|
ProjectName string `url:"-"`
|
|
DeploymentID string `url:"-"`
|
|
Force bool `url:"force,omitempty"`
|
|
}
|
|
|
|
type CreatePagesDeploymentParams struct {
|
|
ProjectName string `json:"-"`
|
|
Branch string `json:"branch,omitempty"`
|
|
}
|
|
|
|
type RetryPagesDeploymentParams struct {
|
|
ProjectName string
|
|
DeploymentID string
|
|
}
|
|
|
|
type RollbackPagesDeploymentParams struct {
|
|
ProjectName string
|
|
DeploymentID string
|
|
}
|
|
|
|
var (
|
|
ErrMissingProjectName = errors.New("required missing project name")
|
|
ErrMissingDeploymentID = errors.New("required missing deployment ID")
|
|
)
|
|
|
|
// ListPagesDeployments returns all deployments for a Pages project.
|
|
//
|
|
// API reference: https://api.cloudflare.com/#pages-deployment-get-deployments
|
|
func (api *API) ListPagesDeployments(ctx context.Context, rc *ResourceContainer, params ListPagesDeploymentsParams) ([]PagesProjectDeployment, *ResultInfo, error) {
|
|
if rc.Identifier == "" {
|
|
return []PagesProjectDeployment{}, &ResultInfo{}, ErrMissingAccountID
|
|
}
|
|
|
|
if params.ProjectName == "" {
|
|
return []PagesProjectDeployment{}, &ResultInfo{}, ErrMissingProjectName
|
|
}
|
|
|
|
autoPaginate := true
|
|
if params.PerPage >= 1 || params.Page >= 1 {
|
|
autoPaginate = false
|
|
}
|
|
|
|
if params.PerPage < 1 {
|
|
params.PerPage = 25
|
|
}
|
|
|
|
if params.Page < 1 {
|
|
params.Page = 1
|
|
}
|
|
|
|
var deployments []PagesProjectDeployment
|
|
var r pagesDeploymentListResponse
|
|
|
|
for {
|
|
uri := buildURI(fmt.Sprintf("/accounts/%s/pages/projects/%s/deployments", rc.Identifier, params.ProjectName), params)
|
|
res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
|
|
if err != nil {
|
|
return []PagesProjectDeployment{}, &ResultInfo{}, err
|
|
}
|
|
err = json.Unmarshal(res, &r)
|
|
if err != nil {
|
|
return []PagesProjectDeployment{}, &ResultInfo{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
|
|
}
|
|
deployments = append(deployments, r.Result...)
|
|
params.ResultInfo = r.ResultInfo.Next()
|
|
if params.Done() || !autoPaginate {
|
|
break
|
|
}
|
|
}
|
|
return deployments, &r.ResultInfo, nil
|
|
}
|
|
|
|
// GetPagesDeploymentInfo returns a deployment for a Pages project.
|
|
//
|
|
// API reference: https://api.cloudflare.com/#pages-deployment-get-deployment-info
|
|
func (api *API) GetPagesDeploymentInfo(ctx context.Context, rc *ResourceContainer, projectName, deploymentID string) (PagesProjectDeployment, error) {
|
|
if rc.Identifier == "" {
|
|
return PagesProjectDeployment{}, ErrMissingAccountID
|
|
}
|
|
|
|
if projectName == "" {
|
|
return PagesProjectDeployment{}, ErrMissingProjectName
|
|
}
|
|
|
|
if deploymentID == "" {
|
|
return PagesProjectDeployment{}, ErrMissingDeploymentID
|
|
}
|
|
|
|
uri := fmt.Sprintf("/accounts/%s/pages/projects/%s/deployments/%s", rc.Identifier, projectName, deploymentID)
|
|
|
|
res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
|
|
if err != nil {
|
|
return PagesProjectDeployment{}, err
|
|
}
|
|
var r pagesDeploymentResponse
|
|
err = json.Unmarshal(res, &r)
|
|
if err != nil {
|
|
return PagesProjectDeployment{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
|
|
}
|
|
return r.Result, nil
|
|
}
|
|
|
|
// GetPagesDeploymentLogs returns the logs for a Pages deployment.
|
|
//
|
|
// API reference: https://api.cloudflare.com/#pages-deployment-get-deployment-logs
|
|
func (api *API) GetPagesDeploymentLogs(ctx context.Context, rc *ResourceContainer, params GetPagesDeploymentLogsParams) (PagesDeploymentLogs, error) {
|
|
if rc.Identifier == "" {
|
|
return PagesDeploymentLogs{}, ErrMissingAccountID
|
|
}
|
|
|
|
if params.ProjectName == "" {
|
|
return PagesDeploymentLogs{}, ErrMissingProjectName
|
|
}
|
|
|
|
if params.DeploymentID == "" {
|
|
return PagesDeploymentLogs{}, ErrMissingDeploymentID
|
|
}
|
|
|
|
uri := buildURI(
|
|
fmt.Sprintf("/accounts/%s/pages/projects/%s/deployments/%s/history/logs", rc.Identifier, params.ProjectName, params.DeploymentID),
|
|
params.SizeOptions,
|
|
)
|
|
|
|
res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
|
|
if err != nil {
|
|
return PagesDeploymentLogs{}, err
|
|
}
|
|
var r pagesDeploymentLogsResponse
|
|
err = json.Unmarshal(res, &r)
|
|
if err != nil {
|
|
return PagesDeploymentLogs{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
|
|
}
|
|
return r.Result, nil
|
|
}
|
|
|
|
// DeletePagesDeployment deletes a Pages deployment.
|
|
//
|
|
// API reference: https://api.cloudflare.com/#pages-deployment-delete-deployment
|
|
func (api *API) DeletePagesDeployment(ctx context.Context, rc *ResourceContainer, params DeletePagesDeploymentParams) error {
|
|
if rc.Identifier == "" {
|
|
return ErrMissingAccountID
|
|
}
|
|
|
|
if params.ProjectName == "" {
|
|
return ErrMissingProjectName
|
|
}
|
|
|
|
if params.DeploymentID == "" {
|
|
return ErrMissingDeploymentID
|
|
}
|
|
|
|
uri := buildURI(fmt.Sprintf("/accounts/%s/pages/projects/%s/deployments/%s", rc.Identifier, params.ProjectName, params.DeploymentID), params)
|
|
|
|
_, err := api.makeRequestContext(ctx, http.MethodDelete, uri, nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// CreatePagesDeployment creates a Pages production deployment.
|
|
//
|
|
// API reference: https://api.cloudflare.com/#pages-deployment-create-deployment
|
|
func (api *API) CreatePagesDeployment(ctx context.Context, rc *ResourceContainer, params CreatePagesDeploymentParams) (PagesProjectDeployment, error) {
|
|
if rc.Identifier == "" {
|
|
return PagesProjectDeployment{}, ErrMissingAccountID
|
|
}
|
|
|
|
if params.ProjectName == "" {
|
|
return PagesProjectDeployment{}, ErrMissingProjectName
|
|
}
|
|
|
|
uri := fmt.Sprintf("/accounts/%s/pages/projects/%s/deployments", rc.Identifier, params.ProjectName)
|
|
|
|
res, err := api.makeRequestContext(ctx, http.MethodPost, uri, params)
|
|
if err != nil {
|
|
return PagesProjectDeployment{}, err
|
|
}
|
|
var r pagesDeploymentResponse
|
|
err = json.Unmarshal(res, &r)
|
|
if err != nil {
|
|
return PagesProjectDeployment{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
|
|
}
|
|
return r.Result, nil
|
|
}
|
|
|
|
// RetryPagesDeployment retries a specific Pages deployment.
|
|
//
|
|
// API reference: https://api.cloudflare.com/#pages-deployment-retry-deployment
|
|
func (api *API) RetryPagesDeployment(ctx context.Context, rc *ResourceContainer, projectName, deploymentID string) (PagesProjectDeployment, error) {
|
|
if rc.Identifier == "" {
|
|
return PagesProjectDeployment{}, ErrMissingAccountID
|
|
}
|
|
|
|
if projectName == "" {
|
|
return PagesProjectDeployment{}, ErrMissingProjectName
|
|
}
|
|
|
|
if deploymentID == "" {
|
|
return PagesProjectDeployment{}, ErrMissingDeploymentID
|
|
}
|
|
|
|
uri := fmt.Sprintf("/accounts/%s/pages/projects/%s/deployments/%s/retry", rc.Identifier, projectName, deploymentID)
|
|
|
|
res, err := api.makeRequestContext(ctx, http.MethodPost, uri, nil)
|
|
if err != nil {
|
|
return PagesProjectDeployment{}, err
|
|
}
|
|
var r pagesDeploymentResponse
|
|
err = json.Unmarshal(res, &r)
|
|
if err != nil {
|
|
return PagesProjectDeployment{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
|
|
}
|
|
return r.Result, nil
|
|
}
|
|
|
|
// RollbackPagesDeployment rollbacks the Pages production deployment to a previous production deployment.
|
|
//
|
|
// API reference: https://api.cloudflare.com/#pages-deployment-rollback-deployment
|
|
func (api *API) RollbackPagesDeployment(ctx context.Context, rc *ResourceContainer, projectName, deploymentID string) (PagesProjectDeployment, error) {
|
|
if rc.Identifier == "" {
|
|
return PagesProjectDeployment{}, ErrMissingAccountID
|
|
}
|
|
|
|
if projectName == "" {
|
|
return PagesProjectDeployment{}, ErrMissingProjectName
|
|
}
|
|
|
|
if deploymentID == "" {
|
|
return PagesProjectDeployment{}, ErrMissingDeploymentID
|
|
}
|
|
|
|
uri := fmt.Sprintf("/accounts/%s/pages/projects/%s/deployments/%s/rollback", rc.Identifier, projectName, deploymentID)
|
|
|
|
res, err := api.makeRequestContext(ctx, http.MethodPost, uri, nil)
|
|
if err != nil {
|
|
return PagesProjectDeployment{}, err
|
|
}
|
|
var r pagesDeploymentResponse
|
|
err = json.Unmarshal(res, &r)
|
|
if err != nil {
|
|
return PagesProjectDeployment{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
|
|
}
|
|
return r.Result, nil
|
|
}
|