github.com/akamai/AkamaiOPEN-edgegrid-golang/v8@v8.1.0/pkg/cloudlets/v3/policy.go (about)

     1  package v3
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  	"net/http"
     8  	"net/url"
     9  	"regexp"
    10  	"strconv"
    11  	"time"
    12  
    13  	"github.com/akamai/AkamaiOPEN-edgegrid-golang/v8/pkg/edgegriderr"
    14  	validation "github.com/go-ozzo/ozzo-validation/v4"
    15  )
    16  
    17  type (
    18  	// ListPoliciesRequest contains request parameters for ListPolicies
    19  	ListPoliciesRequest struct {
    20  		Page int
    21  		Size int
    22  	}
    23  
    24  	// CreatePolicyRequest contains request parameters for CreatePolicy
    25  	CreatePolicyRequest struct {
    26  		CloudletType CloudletType `json:"cloudletType"`
    27  		Description  *string      `json:"description,omitempty"`
    28  		GroupID      int64        `json:"groupId"`
    29  		Name         string       `json:"name"`
    30  		PolicyType   PolicyType   `json:"policyType,omitempty"`
    31  	}
    32  
    33  	// DeletePolicyRequest contains request parameters for DeletePolicy
    34  	DeletePolicyRequest struct {
    35  		PolicyID int64
    36  	}
    37  
    38  	// GetPolicyRequest contains request parameters for GetPolicy
    39  	GetPolicyRequest struct {
    40  		PolicyID int64
    41  	}
    42  
    43  	// UpdatePolicyRequest contains request parameters for UpdatePolicy
    44  	UpdatePolicyRequest struct {
    45  		PolicyID   int64
    46  		BodyParams UpdatePolicyBodyParams
    47  	}
    48  
    49  	// ClonePolicyRequest contains request parameters for ClonePolicy
    50  	ClonePolicyRequest struct {
    51  		PolicyID   int64
    52  		BodyParams ClonePolicyBodyParams
    53  	}
    54  
    55  	// ClonePolicyBodyParams contains request body parameters used in ClonePolicy operation
    56  	// GroupID is required only when cloning v2
    57  	ClonePolicyBodyParams struct {
    58  		AdditionalVersions []int64 `json:"additionalVersions,omitempty"`
    59  		GroupID            int64   `json:"groupId,omitempty"`
    60  		NewName            string  `json:"newName"`
    61  	}
    62  
    63  	// UpdatePolicyBodyParams contains request body parameters used in UpdatePolicy operation
    64  	UpdatePolicyBodyParams struct {
    65  		GroupID     int64   `json:"groupId"`
    66  		Description *string `json:"description,omitempty"`
    67  	}
    68  
    69  	// PolicyType represents the type of the policy
    70  	PolicyType string
    71  
    72  	// CloudletType represents the type of the cloudlet
    73  	CloudletType string
    74  
    75  	// ListPoliciesResponse contains the response data from ListPolicies operation
    76  	ListPoliciesResponse struct {
    77  		Content []Policy `json:"content"`
    78  		Links   []Link   `json:"links"`
    79  		Page    Page     `json:"page"`
    80  	}
    81  
    82  	// Policy contains information about shared policy
    83  	Policy struct {
    84  		CloudletType       CloudletType       `json:"cloudletType"`
    85  		CreatedBy          string             `json:"createdBy"`
    86  		CreatedDate        time.Time          `json:"createdDate"`
    87  		CurrentActivations CurrentActivations `json:"currentActivations"`
    88  		Description        *string            `json:"description"`
    89  		GroupID            int64              `json:"groupId"`
    90  		ID                 int64              `json:"id"`
    91  		Links              []Link             `json:"links"`
    92  		ModifiedBy         string             `json:"modifiedBy"`
    93  		ModifiedDate       *time.Time         `json:"modifiedDate,omitempty"`
    94  		Name               string             `json:"name"`
    95  		PolicyType         PolicyType         `json:"policyType"`
    96  	}
    97  
    98  	// CurrentActivations contains information about the active policy version that's currently in use and the status of the most recent activation
    99  	// or deactivation operation on the policy's versions for the production and staging networks
   100  	CurrentActivations struct {
   101  		Production ActivationInfo `json:"production"`
   102  		Staging    ActivationInfo `json:"staging"`
   103  	}
   104  
   105  	// ActivationInfo contains information about effective and latest activations
   106  	ActivationInfo struct {
   107  		Effective *PolicyActivation `json:"effective"`
   108  		Latest    *PolicyActivation `json:"latest"`
   109  	}
   110  )
   111  
   112  const (
   113  	// PolicyTypeShared represents policy of type SHARED
   114  	PolicyTypeShared = PolicyType("SHARED")
   115  	// CloudletTypeAP represents cloudlet of type AP
   116  	CloudletTypeAP = CloudletType("AP")
   117  	// CloudletTypeAS represents cloudlet of type AS
   118  	CloudletTypeAS = CloudletType("AS")
   119  	// CloudletTypeCD represents cloudlet of type CD
   120  	CloudletTypeCD = CloudletType("CD")
   121  	// CloudletTypeER represents cloudlet of type ER
   122  	CloudletTypeER = CloudletType("ER")
   123  	// CloudletTypeFR represents cloudlet of type FR
   124  	CloudletTypeFR = CloudletType("FR")
   125  	// CloudletTypeIG represents cloudlet of type IG
   126  	CloudletTypeIG = CloudletType("IG")
   127  )
   128  
   129  var (
   130  	// ErrListPolicies is returned when ListPolicies fails
   131  	ErrListPolicies = errors.New("list shared policies")
   132  	// ErrCreatePolicy is returned when CreatePolicy fails
   133  	ErrCreatePolicy = errors.New("create shared policy")
   134  	// ErrDeletePolicy is returned when DeletePolicy fails
   135  	ErrDeletePolicy = errors.New("delete shared policy")
   136  	// ErrGetPolicy is returned when GetPolicy fails
   137  	ErrGetPolicy = errors.New("get shared policy")
   138  	// ErrUpdatePolicy is returned when UpdatePolicy fails
   139  	ErrUpdatePolicy = errors.New("update shared policy")
   140  	// ErrClonePolicy is returned when ClonePolicy fails
   141  	ErrClonePolicy = errors.New("clone policy")
   142  )
   143  
   144  // Validate validates ListPoliciesRequest
   145  func (r ListPoliciesRequest) Validate() error {
   146  	return edgegriderr.ParseValidationErrors(validation.Errors{
   147  		"Page": validation.Validate(r.Page, validation.Min(0)),
   148  		"Size": validation.Validate(r.Size, validation.Min(10)),
   149  	})
   150  }
   151  
   152  // Validate validates CreatePolicyRequest
   153  func (r CreatePolicyRequest) Validate() error {
   154  	return edgegriderr.ParseValidationErrors(validation.Errors{
   155  		"CloudletType": validation.Validate(r.CloudletType, validation.Required, validation.In(CloudletTypeAP, CloudletTypeAS, CloudletTypeCD, CloudletTypeER, CloudletTypeFR, CloudletTypeIG).
   156  			Error(fmt.Sprintf("value '%s' is invalid. Must be one of: '%s', '%s', '%s', '%s', '%s', '%s'", r.CloudletType, CloudletTypeAP, CloudletTypeAS, CloudletTypeCD, CloudletTypeER, CloudletTypeFR, CloudletTypeIG))),
   157  		"Name": validation.Validate(r.Name, validation.Required, validation.Length(0, 64), validation.Match(regexp.MustCompile("^[a-z_A-Z0-9]+$")).
   158  			Error(fmt.Sprintf("value '%s' is invalid. Must be of format: ^[a-z_A-Z0-9]+$", r.Name))),
   159  		"GroupID":     validation.Validate(r.GroupID, validation.Required),
   160  		"Description": validation.Validate(r.Description, validation.Length(0, 255)),
   161  		"PolicyType":  validation.Validate(r.PolicyType, validation.In(PolicyTypeShared).Error(fmt.Sprintf("value '%s' is invalid. Must be '%s'", r.PolicyType, PolicyTypeShared))),
   162  	})
   163  }
   164  
   165  // Validate validates DeletePolicyRequest
   166  func (r DeletePolicyRequest) Validate() error {
   167  	return edgegriderr.ParseValidationErrors(validation.Errors{
   168  		"PolicyID": validation.Validate(r.PolicyID, validation.Required),
   169  	})
   170  }
   171  
   172  // Validate validates GetPolicyRequest
   173  func (r GetPolicyRequest) Validate() error {
   174  	return edgegriderr.ParseValidationErrors(validation.Errors{
   175  		"PolicyID": validation.Validate(r.PolicyID, validation.Required),
   176  	})
   177  }
   178  
   179  // Validate validates UpdatePolicyRequest
   180  func (r UpdatePolicyRequest) Validate() error {
   181  	return edgegriderr.ParseValidationErrors(validation.Errors{
   182  		"PolicyID":   validation.Validate(r.PolicyID, validation.Required),
   183  		"BodyParams": validation.Validate(r.BodyParams, validation.Required),
   184  	})
   185  }
   186  
   187  // Validate validates UpdatePolicyBodyParams
   188  func (b UpdatePolicyBodyParams) Validate() error {
   189  	return validation.Errors{
   190  		"GroupID":     validation.Validate(b.GroupID, validation.Required),
   191  		"Description": validation.Validate(b.Description, validation.Length(0, 255)),
   192  	}.Filter()
   193  }
   194  
   195  // Validate validates ClonePolicyRequest
   196  func (r ClonePolicyRequest) Validate() error {
   197  	return edgegriderr.ParseValidationErrors(validation.Errors{
   198  		"PolicyID":   validation.Validate(r.PolicyID, validation.Required),
   199  		"BodyParams": validation.Validate(r.BodyParams, validation.Required),
   200  	})
   201  }
   202  
   203  // Validate validates ClonePolicyBodyParams
   204  func (b ClonePolicyBodyParams) Validate() error {
   205  	return validation.Errors{
   206  		"NewName": validation.Validate(b.NewName, validation.Required, validation.Length(0, 64), validation.Match(regexp.MustCompile("^[a-z_A-Z0-9]+$")).
   207  			Error(fmt.Sprintf("value '%s' is invalid. Must be of format: ^[a-z_A-Z0-9]+$", b.NewName))),
   208  	}.Filter()
   209  }
   210  
   211  func (c *cloudlets) ListPolicies(ctx context.Context, params ListPoliciesRequest) (*ListPoliciesResponse, error) {
   212  	logger := c.Log(ctx)
   213  	logger.Debug("ListPolicies")
   214  
   215  	if err := params.Validate(); err != nil {
   216  		return nil, fmt.Errorf("%s: %w: %s", ErrListPolicies, ErrStructValidation, err)
   217  	}
   218  
   219  	uri, err := url.Parse("/cloudlets/v3/policies")
   220  	if err != nil {
   221  		return nil, fmt.Errorf("%w: failed to parse url: %s", ErrListPolicies, err)
   222  	}
   223  
   224  	q := uri.Query()
   225  	if params.Size != 0 {
   226  		q.Add("size", strconv.Itoa(params.Size))
   227  	}
   228  	if params.Page != 0 {
   229  		q.Add("page", strconv.Itoa(params.Page))
   230  	}
   231  
   232  	uri.RawQuery = q.Encode()
   233  
   234  	req, err := http.NewRequestWithContext(ctx, http.MethodGet, uri.String(), nil)
   235  	if err != nil {
   236  		return nil, fmt.Errorf("%w: failed to create request: %s", ErrListPolicies, err)
   237  	}
   238  
   239  	var result ListPoliciesResponse
   240  	resp, err := c.Exec(req, &result)
   241  	if err != nil {
   242  		return nil, fmt.Errorf("%w: request failed: %s", ErrListPolicies, err)
   243  	}
   244  
   245  	if resp.StatusCode != http.StatusOK {
   246  		return nil, fmt.Errorf("%s: %w", ErrListPolicies, c.Error(resp))
   247  	}
   248  
   249  	return &result, nil
   250  }
   251  
   252  func (c *cloudlets) CreatePolicy(ctx context.Context, params CreatePolicyRequest) (*Policy, error) {
   253  	logger := c.Log(ctx)
   254  	logger.Debug("CreatePolicy")
   255  
   256  	if err := params.Validate(); err != nil {
   257  		return nil, fmt.Errorf("%s: %w: %s", ErrCreatePolicy, ErrStructValidation, err)
   258  	}
   259  
   260  	uri := "/cloudlets/v3/policies"
   261  
   262  	req, err := http.NewRequestWithContext(ctx, http.MethodPost, uri, nil)
   263  	if err != nil {
   264  		return nil, fmt.Errorf("%w: failed to create request: %s", ErrCreatePolicy, err)
   265  	}
   266  
   267  	var result Policy
   268  	resp, err := c.Exec(req, &result, params)
   269  	if err != nil {
   270  		return nil, fmt.Errorf("%w: request failed: %s", ErrCreatePolicy, err)
   271  	}
   272  
   273  	if resp.StatusCode != http.StatusCreated {
   274  		return nil, fmt.Errorf("%s: %w", ErrCreatePolicy, c.Error(resp))
   275  	}
   276  
   277  	return &result, nil
   278  }
   279  
   280  func (c *cloudlets) DeletePolicy(ctx context.Context, params DeletePolicyRequest) error {
   281  	logger := c.Log(ctx)
   282  	logger.Debug("DeletePolicy")
   283  
   284  	if err := params.Validate(); err != nil {
   285  		return fmt.Errorf("%s: %w: %s", ErrDeletePolicy, ErrStructValidation, err)
   286  	}
   287  
   288  	uri := fmt.Sprintf("/cloudlets/v3/policies/%d", params.PolicyID)
   289  
   290  	req, err := http.NewRequestWithContext(ctx, http.MethodDelete, uri, nil)
   291  	if err != nil {
   292  		return fmt.Errorf("%w: failed to create request: %s", ErrDeletePolicy, err)
   293  	}
   294  
   295  	resp, err := c.Exec(req, nil)
   296  	if err != nil {
   297  		return fmt.Errorf("%w: request failed: %s", ErrDeletePolicy, err)
   298  	}
   299  
   300  	if resp.StatusCode != http.StatusNoContent {
   301  		return fmt.Errorf("%s: %w", ErrDeletePolicy, c.Error(resp))
   302  	}
   303  
   304  	return nil
   305  }
   306  
   307  func (c *cloudlets) GetPolicy(ctx context.Context, params GetPolicyRequest) (*Policy, error) {
   308  	logger := c.Log(ctx)
   309  	logger.Debug("GetPolicy")
   310  
   311  	if err := params.Validate(); err != nil {
   312  		return nil, fmt.Errorf("%s: %w: %s", ErrGetPolicy, ErrStructValidation, err)
   313  	}
   314  
   315  	uri := fmt.Sprintf("/cloudlets/v3/policies/%d", params.PolicyID)
   316  
   317  	req, err := http.NewRequestWithContext(ctx, http.MethodGet, uri, nil)
   318  	if err != nil {
   319  		return nil, fmt.Errorf("%w: failed to create request: %s", ErrGetPolicy, err)
   320  	}
   321  
   322  	var result Policy
   323  	resp, err := c.Exec(req, &result)
   324  	if err != nil {
   325  		return nil, fmt.Errorf("%w: request failed: %s", ErrGetPolicy, err)
   326  	}
   327  
   328  	if resp.StatusCode == http.StatusNotFound {
   329  		return nil, fmt.Errorf("%s: %w: %s", ErrGetPolicy, ErrPolicyNotFound, c.Error(resp))
   330  	}
   331  
   332  	if resp.StatusCode != http.StatusOK {
   333  		return nil, fmt.Errorf("%s: %w", ErrGetPolicy, c.Error(resp))
   334  	}
   335  
   336  	return &result, nil
   337  }
   338  
   339  func (c *cloudlets) UpdatePolicy(ctx context.Context, params UpdatePolicyRequest) (*Policy, error) {
   340  	logger := c.Log(ctx)
   341  	logger.Debug("UpdatePolicy")
   342  
   343  	if err := params.Validate(); err != nil {
   344  		return nil, fmt.Errorf("%s: %w: %s", ErrUpdatePolicy, ErrStructValidation, err)
   345  	}
   346  
   347  	uri := fmt.Sprintf("/cloudlets/v3/policies/%d", params.PolicyID)
   348  
   349  	req, err := http.NewRequestWithContext(ctx, http.MethodPut, uri, nil)
   350  	if err != nil {
   351  		return nil, fmt.Errorf("%w: failed to create request: %s", ErrUpdatePolicy, err)
   352  	}
   353  
   354  	var result Policy
   355  	resp, err := c.Exec(req, &result, params.BodyParams)
   356  	if err != nil {
   357  		return nil, fmt.Errorf("%w: request failed: %s", ErrUpdatePolicy, err)
   358  	}
   359  
   360  	if resp.StatusCode != http.StatusOK {
   361  		return nil, fmt.Errorf("%s: %w", ErrUpdatePolicy, c.Error(resp))
   362  	}
   363  
   364  	return &result, nil
   365  }
   366  
   367  func (c *cloudlets) ClonePolicy(ctx context.Context, params ClonePolicyRequest) (*Policy, error) {
   368  	logger := c.Log(ctx)
   369  	logger.Debug("ClonePolicy")
   370  
   371  	if err := params.Validate(); err != nil {
   372  		return nil, fmt.Errorf("%s: %w: %s", ErrClonePolicy, ErrStructValidation, err)
   373  	}
   374  
   375  	uri := fmt.Sprintf("/cloudlets/v3/policies/%d/clone", params.PolicyID)
   376  
   377  	req, err := http.NewRequestWithContext(ctx, http.MethodPost, uri, nil)
   378  	if err != nil {
   379  		return nil, fmt.Errorf("%w: failed to create request: %s", ErrClonePolicy, err)
   380  	}
   381  
   382  	var result Policy
   383  	resp, err := c.Exec(req, &result, params.BodyParams)
   384  	if err != nil {
   385  		return nil, fmt.Errorf("%w: request failed: %s", ErrClonePolicy, err)
   386  	}
   387  
   388  	if resp.StatusCode != http.StatusOK {
   389  		return nil, fmt.Errorf("%s: %w", ErrClonePolicy, c.Error(resp))
   390  	}
   391  
   392  	return &result, nil
   393  }