github.com/akamai/AkamaiOPEN-edgegrid-golang/v2@v2.17.0/pkg/configgtm/resource.go (about)

     1  package gtm
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"net/http"
     7  )
     8  
     9  //
    10  // Handle Operations on gtm resources
    11  // Based on 1.4 schema
    12  //
    13  
    14  // Resources contains operations available on a Resource resource
    15  // See: https://developer.akamai.com/api/web_performance/global_traffic_management/v1.html
    16  type Resources interface {
    17  	// NewResourceInstance instantiates a new ResourceInstance.
    18  	NewResourceInstance(context.Context, *Resource, int) *ResourceInstance
    19  	// NewResource creates a new Resource object.
    20  	NewResource(context.Context, string) *Resource
    21  	// ListResources retreieves all Resources
    22  	// See: https://developer.akamai.com/api/web_performance/global_traffic_management/v1.html#getresources
    23  	ListResources(context.Context, string) ([]*Resource, error)
    24  	// GetResource retrieves a Resource with the given name.
    25  	// See: https://developer.akamai.com/api/web_performance/global_traffic_management/v1.html#getresource
    26  	GetResource(context.Context, string, string) (*Resource, error)
    27  	// Create the datacenter identified by the receiver argument in the specified domain.
    28  	// See: https://developer.akamai.com/api/web_performance/global_traffic_management/v1.html#putresource
    29  	CreateResource(context.Context, *Resource, string) (*ResourceResponse, error)
    30  	// Delete the datacenter identified by the receiver argument from the domain specified.
    31  	// See: https://developer.akamai.com/api/web_performance/global_traffic_management/v1.html#deleteresource
    32  	DeleteResource(context.Context, *Resource, string) (*ResponseStatus, error)
    33  	// Update the datacenter identified in the receiver argument in the provided domain.
    34  	// See: https://developer.akamai.com/api/web_performance/global_traffic_management/v1.html#putresource
    35  	UpdateResource(context.Context, *Resource, string) (*ResponseStatus, error)
    36  }
    37  
    38  // ResourceInstance contains information about the resources that constrain the properties within the data center
    39  type ResourceInstance struct {
    40  	DatacenterId         int  `json:"datacenterId"`
    41  	UseDefaultLoadObject bool `json:"useDefaultLoadObject"`
    42  	LoadObject
    43  }
    44  
    45  // Resource represents a GTM resource
    46  type Resource struct {
    47  	Type                        string              `json:"type"`
    48  	HostHeader                  string              `json:"hostHeader,omitempty"`
    49  	LeastSquaresDecay           float64             `json:"leastSquaresDecay,omitempty"`
    50  	Description                 string              `json:"description,omitempty"`
    51  	LeaderString                string              `json:"leaderString,omitempty"`
    52  	ConstrainedProperty         string              `json:"constrainedProperty,omitempty"`
    53  	ResourceInstances           []*ResourceInstance `json:"resourceInstances,omitempty"`
    54  	AggregationType             string              `json:"aggregationType,omitempty"`
    55  	Links                       []*Link             `json:"links,omitempty"`
    56  	LoadImbalancePercentage     float64             `json:"loadImbalancePercentage,omitempty"`
    57  	UpperBound                  int                 `json:"upperBound,omitempty"`
    58  	Name                        string              `json:"name"`
    59  	MaxUMultiplicativeIncrement float64             `json:"maxUMultiplicativeIncrement,omitempty"`
    60  	DecayRate                   float64             `json:"decayRate,omitempty"`
    61  }
    62  
    63  // ResourceList is the structure returned by List Resources
    64  type ResourceList struct {
    65  	ResourceItems []*Resource `json:"items"`
    66  }
    67  
    68  // Validate validates Resource
    69  func (rsrc *Resource) Validate() error {
    70  
    71  	if len(rsrc.Name) < 1 {
    72  		return fmt.Errorf("Resource is missing Name")
    73  	}
    74  	if len(rsrc.Type) < 1 {
    75  		return fmt.Errorf("Resource is missing Type")
    76  	}
    77  
    78  	return nil
    79  }
    80  
    81  // NewResourceInstance instantiates a new ResourceInstance.
    82  func (p *gtm) NewResourceInstance(ctx context.Context, _ *Resource, dcID int) *ResourceInstance {
    83  
    84  	logger := p.Log(ctx)
    85  	logger.Debug("NewResourceInstance")
    86  
    87  	return &ResourceInstance{DatacenterId: dcID}
    88  
    89  }
    90  
    91  // NewResource creates a new Resource object.
    92  func (p *gtm) NewResource(ctx context.Context, name string) *Resource {
    93  
    94  	logger := p.Log(ctx)
    95  	logger.Debug("NewResource")
    96  
    97  	resource := &Resource{Name: name}
    98  	return resource
    99  }
   100  
   101  // ListResources retreieves all Resources in the specified domain.
   102  func (p *gtm) ListResources(ctx context.Context, domainName string) ([]*Resource, error) {
   103  
   104  	logger := p.Log(ctx)
   105  	logger.Debug("ListResources")
   106  
   107  	var rsrcs ResourceList
   108  	getURL := fmt.Sprintf("/config-gtm/v1/domains/%s/resources", domainName)
   109  	req, err := http.NewRequestWithContext(ctx, http.MethodGet, getURL, nil)
   110  	if err != nil {
   111  		return nil, fmt.Errorf("failed to create ListResources request: %w", err)
   112  	}
   113  	setVersionHeader(req, schemaVersion)
   114  	resp, err := p.Exec(req, &rsrcs)
   115  	if err != nil {
   116  		return nil, fmt.Errorf("ListResources request failed: %w", err)
   117  	}
   118  
   119  	if resp.StatusCode != http.StatusOK {
   120  		return nil, p.Error(resp)
   121  	}
   122  
   123  	return rsrcs.ResourceItems, nil
   124  }
   125  
   126  // GetResource retrieves a Resource with the given name in the specified domain.
   127  func (p *gtm) GetResource(ctx context.Context, name, domainName string) (*Resource, error) {
   128  
   129  	logger := p.Log(ctx)
   130  	logger.Debug("GetResource")
   131  
   132  	var rsc Resource
   133  	getURL := fmt.Sprintf("/config-gtm/v1/domains/%s/resources/%s", domainName, name)
   134  	req, err := http.NewRequestWithContext(ctx, http.MethodGet, getURL, nil)
   135  	if err != nil {
   136  		return nil, fmt.Errorf("failed to create GetResource request: %w", err)
   137  	}
   138  	setVersionHeader(req, schemaVersion)
   139  	resp, err := p.Exec(req, &rsc)
   140  	if err != nil {
   141  		return nil, fmt.Errorf("GetResource request failed: %w", err)
   142  	}
   143  
   144  	if resp.StatusCode != http.StatusOK {
   145  		return nil, p.Error(resp)
   146  	}
   147  
   148  	return &rsc, nil
   149  }
   150  
   151  // CreateResource creates the resource identified by the receiver argument in the specified domain.
   152  func (p *gtm) CreateResource(ctx context.Context, rsrc *Resource, domainName string) (*ResourceResponse, error) {
   153  
   154  	logger := p.Log(ctx)
   155  	logger.Debug("CreateResource")
   156  
   157  	// Use common code. Any specific validation needed?
   158  	return rsrc.save(ctx, p, domainName)
   159  
   160  }
   161  
   162  // UpdateResource updates the resource identified in the receiver argument in the specified domain.
   163  func (p *gtm) UpdateResource(ctx context.Context, rsrc *Resource, domainName string) (*ResponseStatus, error) {
   164  
   165  	logger := p.Log(ctx)
   166  	logger.Debug("UpdateResource")
   167  
   168  	// common code
   169  	stat, err := rsrc.save(ctx, p, domainName)
   170  	if err != nil {
   171  		return nil, err
   172  	}
   173  	return stat.Status, err
   174  
   175  }
   176  
   177  // save is a methon that saves Resource in given domain. Common path for Create and Update.
   178  func (rsrc *Resource) save(ctx context.Context, p *gtm, domainName string) (*ResourceResponse, error) {
   179  
   180  	if err := rsrc.Validate(); err != nil {
   181  		return nil, fmt.Errorf("Resource validation failed. %w", err)
   182  	}
   183  
   184  	putURL := fmt.Sprintf("/config-gtm/v1/domains/%s/resources/%s", domainName, rsrc.Name)
   185  	req, err := http.NewRequestWithContext(ctx, http.MethodPut, putURL, nil)
   186  	if err != nil {
   187  		return nil, fmt.Errorf("failed to create Resource request: %w", err)
   188  	}
   189  
   190  	var rscresp ResourceResponse
   191  	setVersionHeader(req, schemaVersion)
   192  	resp, err := p.Exec(req, &rscresp, rsrc)
   193  	if err != nil {
   194  		return nil, fmt.Errorf("Resource request failed: %w", err)
   195  	}
   196  
   197  	if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated {
   198  		return nil, p.Error(resp)
   199  	}
   200  
   201  	return &rscresp, nil
   202  
   203  }
   204  
   205  // DeleteResource deletes the resource identified in the receiver argument from the specified domain.
   206  func (p *gtm) DeleteResource(ctx context.Context, rsrc *Resource, domainName string) (*ResponseStatus, error) {
   207  
   208  	logger := p.Log(ctx)
   209  	logger.Debug("DeleteResource")
   210  
   211  	if err := rsrc.Validate(); err != nil {
   212  		logger.Errorf("Resource validation failed. %w", err)
   213  		return nil, fmt.Errorf("Resource validation failed. %w", err)
   214  	}
   215  
   216  	delURL := fmt.Sprintf("/config-gtm/v1/domains/%s/resources/%s", domainName, rsrc.Name)
   217  	req, err := http.NewRequestWithContext(ctx, http.MethodDelete, delURL, nil)
   218  	if err != nil {
   219  		return nil, fmt.Errorf("failed to create Delete request: %w", err)
   220  	}
   221  
   222  	var rscresp ResponseBody
   223  	setVersionHeader(req, schemaVersion)
   224  	resp, err := p.Exec(req, &rscresp)
   225  	if err != nil {
   226  		return nil, fmt.Errorf("Resource request failed: %w", err)
   227  	}
   228  
   229  	if resp.StatusCode != http.StatusOK {
   230  		return nil, p.Error(resp)
   231  	}
   232  
   233  	return rscresp.Status, nil
   234  
   235  }