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

     1  package cloudlets
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  	"net/http"
     8  	"net/url"
     9  	"regexp"
    10  	"strconv"
    11  
    12  	validation "github.com/go-ozzo/ozzo-validation/v4"
    13  )
    14  
    15  type (
    16  	// Policies is a cloudlets policies API interface.
    17  	Policies interface {
    18  		// ListPolicies lists policies.
    19  		//
    20  		// See: https://techdocs.akamai.com/cloudlets/v2/reference/get-policies
    21  		ListPolicies(context.Context, ListPoliciesRequest) ([]Policy, error)
    22  
    23  		// GetPolicy gets policy by policyID.
    24  		//
    25  		// See: https://techdocs.akamai.com/cloudlets/v2/reference/get-policy
    26  		GetPolicy(context.Context, GetPolicyRequest) (*Policy, error)
    27  
    28  		// CreatePolicy creates policy.
    29  		//
    30  		// See: https://techdocs.akamai.com/cloudlets/v2/reference/post-policy
    31  		CreatePolicy(context.Context, CreatePolicyRequest) (*Policy, error)
    32  
    33  		// RemovePolicy removes policy.
    34  		//
    35  		// See: https://techdocs.akamai.com/cloudlets/v2/reference/delete-policy
    36  		RemovePolicy(context.Context, RemovePolicyRequest) error
    37  
    38  		// UpdatePolicy updates policy.
    39  		//
    40  		// See: https://techdocs.akamai.com/cloudlets/v2/reference/put-policy
    41  		UpdatePolicy(context.Context, UpdatePolicyRequest) (*Policy, error)
    42  	}
    43  
    44  	// Policy is response returned by GetPolicy or UpdatePolicy
    45  	Policy struct {
    46  		Location         string             `json:"location"`
    47  		PolicyID         int64              `json:"policyId"`
    48  		GroupID          int64              `json:"groupId"`
    49  		Name             string             `json:"name"`
    50  		Description      string             `json:"description"`
    51  		CreatedBy        string             `json:"createdBy"`
    52  		CreateDate       float64            `json:"createDate"`
    53  		LastModifiedBy   string             `json:"lastModifiedBy"`
    54  		LastModifiedDate float64            `json:"lastModifiedDate"`
    55  		Activations      []PolicyActivation `json:"activations"`
    56  		CloudletID       int64              `json:"cloudletId"`
    57  		CloudletCode     string             `json:"cloudletCode"`
    58  		APIVersion       string             `json:"apiVersion"`
    59  		Deleted          bool               `json:"deleted"`
    60  	}
    61  
    62  	// PolicyActivation represents a policy activation resource
    63  	PolicyActivation struct {
    64  		APIVersion   string                  `json:"apiVersion"`
    65  		Network      PolicyActivationNetwork `json:"network"`
    66  		PolicyInfo   PolicyInfo              `json:"policyInfo"`
    67  		PropertyInfo PropertyInfo            `json:"propertyInfo"`
    68  	}
    69  
    70  	// PolicyInfo represents a policy info resource
    71  	PolicyInfo struct {
    72  		PolicyID       int64                  `json:"policyId"`
    73  		Name           string                 `json:"name"`
    74  		Version        int64                  `json:"version"`
    75  		Status         PolicyActivationStatus `json:"status"`
    76  		StatusDetail   string                 `json:"statusDetail,omitempty"`
    77  		ActivatedBy    string                 `json:"activatedBy"`
    78  		ActivationDate int64                  `json:"activationDate"`
    79  	}
    80  
    81  	// PropertyInfo represents a property info resource
    82  	PropertyInfo struct {
    83  		Name           string                 `json:"name"`
    84  		Version        int64                  `json:"version"`
    85  		GroupID        int64                  `json:"groupId"`
    86  		Status         PolicyActivationStatus `json:"status"`
    87  		ActivatedBy    string                 `json:"activatedBy"`
    88  		ActivationDate int64                  `json:"activationDate"`
    89  	}
    90  
    91  	// PolicyActivationStatus is an activation status type for policy
    92  	PolicyActivationStatus string
    93  
    94  	// GetPolicyRequest describes the body of the get policy request
    95  	GetPolicyRequest struct {
    96  		PolicyID int64
    97  	}
    98  
    99  	// CreatePolicyRequest describes the body of the create policy request
   100  	CreatePolicyRequest struct {
   101  		Name         string `json:"name"`
   102  		CloudletID   int64  `json:"cloudletId"`
   103  		Description  string `json:"description,omitempty"`
   104  		PropertyName string `json:"propertyName,omitempty"`
   105  		GroupID      int64  `json:"groupId,omitempty"`
   106  	}
   107  
   108  	// UpdatePolicy describes the body of the update policy request
   109  	UpdatePolicy struct {
   110  		Name         string `json:"name,omitempty"`
   111  		Description  string `json:"description,omitempty"`
   112  		PropertyName string `json:"propertyName,omitempty"`
   113  		GroupID      int64  `json:"groupId,omitempty"`
   114  		Deleted      bool   `json:"deleted,omitempty"`
   115  	}
   116  
   117  	// ListPoliciesRequest describes the parameters for the list policies request
   118  	ListPoliciesRequest struct {
   119  		CloudletID     *int64
   120  		IncludeDeleted bool
   121  		Offset         int
   122  		PageSize       *int
   123  	}
   124  
   125  	// UpdatePolicyRequest describes the parameters for the update policy request
   126  	UpdatePolicyRequest struct {
   127  		UpdatePolicy
   128  		PolicyID int64
   129  	}
   130  
   131  	// RemovePolicyRequest describes the body of the remove policy request
   132  	RemovePolicyRequest struct {
   133  		PolicyID int64
   134  	}
   135  )
   136  
   137  const (
   138  	// PolicyActivationStatusActive is an activation that is currently active
   139  	PolicyActivationStatusActive PolicyActivationStatus = "active"
   140  	// PolicyActivationStatusDeactivated is an activation that is deactivated
   141  	PolicyActivationStatusDeactivated PolicyActivationStatus = "deactivated"
   142  	// PolicyActivationStatusInactive is an activation that is not active
   143  	PolicyActivationStatusInactive PolicyActivationStatus = "inactive"
   144  	// PolicyActivationStatusPending is status of a pending activation
   145  	PolicyActivationStatusPending PolicyActivationStatus = "pending"
   146  	// PolicyActivationStatusFailed is status of a failed activation
   147  	PolicyActivationStatusFailed PolicyActivationStatus = "failed"
   148  )
   149  
   150  var nameRegexp = regexp.MustCompile("^[a-z_A-Z0-9]+$")
   151  var propertyNameRegexp = regexp.MustCompile("^[a-z_A-Z0-9.\\-]+$")
   152  
   153  // Validate validates CreatePolicyRequest
   154  func (v CreatePolicyRequest) Validate() error {
   155  	return validation.Errors{
   156  		"Name":         validation.Validate(v.Name, validation.Required, validation.Length(0, 64), validation.Match(nameRegexp)),
   157  		"PropertyName": validation.Validate(v.PropertyName, validation.Match(propertyNameRegexp)),
   158  		"CloudletID":   validation.Validate(v.CloudletID, validation.Min(0), validation.Max(13)),
   159  		"Description":  validation.Validate(v.Description, validation.Length(0, 255)),
   160  		"GroupID":      validation.Validate(v.GroupID),
   161  	}.Filter()
   162  }
   163  
   164  // Validate validates UpdatePolicyRequest
   165  func (v UpdatePolicyRequest) Validate() error {
   166  	return validation.Errors{
   167  		"Name":         validation.Validate(v.Name, validation.Length(0, 64), validation.Match(nameRegexp)),
   168  		"Description":  validation.Validate(v.Description, validation.Length(0, 255)),
   169  		"PropertyName": validation.Validate(v.PropertyName, validation.Match(propertyNameRegexp)),
   170  		"GroupID":      validation.Validate(v.GroupID),
   171  		"Deleted":      validation.Validate(v.Deleted),
   172  	}.Filter()
   173  }
   174  
   175  var (
   176  	// ErrListPolicies is returned when ListPolicies fails
   177  	ErrListPolicies = errors.New("list policies")
   178  	// ErrGetPolicy is returned when GetPolicy fails
   179  	ErrGetPolicy = errors.New("get policy")
   180  	// ErrCreatePolicy is returned when CreatePolicy fails
   181  	ErrCreatePolicy = errors.New("create policy")
   182  	// ErrRemovePolicy is returned when RemovePolicy fails
   183  	ErrRemovePolicy = errors.New("remove policy")
   184  	// ErrUpdatePolicy is returned when UpdatePolicy fails
   185  	ErrUpdatePolicy = errors.New("update policy")
   186  )
   187  
   188  func (c *cloudlets) ListPolicies(ctx context.Context, params ListPoliciesRequest) ([]Policy, error) {
   189  	logger := c.Log(ctx)
   190  	logger.Debug("ListPolicies")
   191  
   192  	uri, err := url.Parse("/cloudlets/api/v2/policies")
   193  	if err != nil {
   194  		return nil, fmt.Errorf("%w: failed to parse url: %s", ErrListPolicies, err)
   195  	}
   196  
   197  	q := uri.Query()
   198  	if params.CloudletID != nil {
   199  		q.Add("cloudletId", fmt.Sprintf("%d", *params.CloudletID))
   200  	}
   201  	if params.PageSize != nil {
   202  		q.Add("pageSize", fmt.Sprintf("%d", *params.PageSize))
   203  	}
   204  	q.Add("offset", fmt.Sprintf("%d", params.Offset))
   205  	q.Add("includeDeleted", strconv.FormatBool(params.IncludeDeleted))
   206  	uri.RawQuery = q.Encode()
   207  
   208  	req, err := http.NewRequestWithContext(ctx, http.MethodGet, uri.String(), nil)
   209  	if err != nil {
   210  		return nil, fmt.Errorf("%w: failed to create request: %s", ErrListPolicies, err)
   211  	}
   212  
   213  	var result []Policy
   214  	resp, err := c.Exec(req, &result)
   215  	if err != nil {
   216  		return nil, fmt.Errorf("%w: request failed: %s", ErrListPolicies, err)
   217  	}
   218  
   219  	if resp.StatusCode != http.StatusOK {
   220  		return nil, fmt.Errorf("%s: %w", ErrListPolicies, c.Error(resp))
   221  	}
   222  
   223  	return result, nil
   224  }
   225  
   226  func (c *cloudlets) GetPolicy(ctx context.Context, params GetPolicyRequest) (*Policy, error) {
   227  	logger := c.Log(ctx)
   228  	logger.Debug("GetPolicy")
   229  
   230  	var result Policy
   231  
   232  	uri, err := url.Parse(fmt.Sprintf("/cloudlets/api/v2/policies/%d", params.PolicyID))
   233  	if err != nil {
   234  		return nil, fmt.Errorf("%w: failed to parse url: %s", ErrGetPolicy, err)
   235  	}
   236  
   237  	req, err := http.NewRequestWithContext(ctx, http.MethodGet, uri.String(), nil)
   238  	if err != nil {
   239  		return nil, fmt.Errorf("%w: failed to create request: %s", ErrGetPolicy, err)
   240  	}
   241  
   242  	resp, err := c.Exec(req, &result)
   243  	if err != nil {
   244  		return nil, fmt.Errorf("%w: request failed: %s", ErrGetPolicy, err)
   245  	}
   246  
   247  	if resp.StatusCode != http.StatusOK {
   248  		return nil, fmt.Errorf("%s: %w", ErrGetPolicy, c.Error(resp))
   249  	}
   250  
   251  	return &result, nil
   252  }
   253  
   254  func (c *cloudlets) CreatePolicy(ctx context.Context, params CreatePolicyRequest) (*Policy, error) {
   255  	logger := c.Log(ctx)
   256  	logger.Debug("CreatePolicy")
   257  
   258  	if err := params.Validate(); err != nil {
   259  		return nil, fmt.Errorf("%s: %w: %s", ErrCreatePolicy, ErrStructValidation, err)
   260  	}
   261  
   262  	uri, err := url.Parse("/cloudlets/api/v2/policies")
   263  	if err != nil {
   264  		return nil, fmt.Errorf("%w: failed to parse url: %s", ErrCreatePolicy, err)
   265  	}
   266  
   267  	req, err := http.NewRequestWithContext(ctx, http.MethodPost, uri.String(), nil)
   268  	if err != nil {
   269  		return nil, fmt.Errorf("%w: failed to create request: %s", ErrCreatePolicy, err)
   270  	}
   271  
   272  	var result Policy
   273  
   274  	resp, err := c.Exec(req, &result, params)
   275  	if err != nil {
   276  		return nil, fmt.Errorf("%w: request failed: %s", ErrCreatePolicy, err)
   277  	}
   278  
   279  	if resp.StatusCode != http.StatusCreated {
   280  		return nil, fmt.Errorf("%s: %w", ErrCreatePolicy, c.Error(resp))
   281  	}
   282  
   283  	return &result, nil
   284  }
   285  
   286  func (c *cloudlets) RemovePolicy(ctx context.Context, params RemovePolicyRequest) error {
   287  	logger := c.Log(ctx)
   288  	logger.Debug("RemovePolicy")
   289  
   290  	uri, err := url.Parse(fmt.Sprintf("/cloudlets/api/v2/policies/%d", params.PolicyID))
   291  	if err != nil {
   292  		return fmt.Errorf("%w: failed to parse url: %s", ErrRemovePolicy, err)
   293  	}
   294  
   295  	req, err := http.NewRequestWithContext(ctx, http.MethodDelete, uri.String(), nil)
   296  	if err != nil {
   297  		return fmt.Errorf("%w: failed to create request: %s", ErrRemovePolicy, err)
   298  	}
   299  
   300  	resp, err := c.Exec(req, nil)
   301  	if err != nil {
   302  		return fmt.Errorf("%w: request failed: %s", ErrRemovePolicy, err)
   303  	}
   304  
   305  	if resp.StatusCode != http.StatusNoContent {
   306  		return fmt.Errorf("%s: %w", ErrRemovePolicy, c.Error(resp))
   307  	}
   308  
   309  	return nil
   310  }
   311  
   312  func (c *cloudlets) UpdatePolicy(ctx context.Context, params UpdatePolicyRequest) (*Policy, error) {
   313  	logger := c.Log(ctx)
   314  	logger.Debug("UpdatePolicy")
   315  
   316  	if err := params.Validate(); err != nil {
   317  		return nil, fmt.Errorf("%s: %w: %s", ErrUpdatePolicy, ErrStructValidation, err)
   318  	}
   319  
   320  	uri, err := url.Parse(fmt.Sprintf(
   321  		"/cloudlets/api/v2/policies/%d",
   322  		params.PolicyID),
   323  	)
   324  	if err != nil {
   325  		return nil, fmt.Errorf("%w: failed to parse url: %s", ErrUpdatePolicy, err)
   326  	}
   327  
   328  	req, err := http.NewRequestWithContext(ctx, http.MethodPut, uri.String(), nil)
   329  	if err != nil {
   330  		return nil, fmt.Errorf("%w: failed to create request: %s", ErrUpdatePolicy, err)
   331  	}
   332  
   333  	var result Policy
   334  
   335  	resp, err := c.Exec(req, &result, params.UpdatePolicy)
   336  	if err != nil {
   337  		return nil, fmt.Errorf("%w: request failed: %s", ErrUpdatePolicy, err)
   338  	}
   339  
   340  	if resp.StatusCode != http.StatusOK {
   341  		return nil, fmt.Errorf("%s: %w", ErrUpdatePolicy, c.Error(resp))
   342  	}
   343  
   344  	return &result, nil
   345  }