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