github.com/akamai/AkamaiOPEN-edgegrid-golang/v5@v5.0.0/pkg/gtm/property.go (about)

     1  package gtm
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"net/http"
     7  )
     8  
     9  //
    10  // Support gtm domain properties thru Edgegrid
    11  // Based on 1.4 Schema
    12  //
    13  
    14  // Properties contains operations available on a Property resource.
    15  type Properties interface {
    16  	// NewTrafficTarget is a method applied to a property object that instantiates a TrafficTarget object.
    17  	NewTrafficTarget(context.Context) *TrafficTarget
    18  	// NewStaticRRSet is a method applied to a property object that instantiates a StaticRRSet object.
    19  	NewStaticRRSet(context.Context) *StaticRRSet
    20  	// NewLivenessTest is a method applied to a property object that instantiates a LivenessTest object.
    21  	NewLivenessTest(context.Context, string, string, int, float32) *LivenessTest
    22  	// NewProperty creates a new Property object.
    23  	NewProperty(context.Context, string) *Property
    24  	// ListProperties retreieves all Properties for the provided domainName.
    25  	//
    26  	// See: https://techdocs.akamai.com/gtm/reference/get-properties
    27  	ListProperties(context.Context, string) ([]*Property, error)
    28  	// GetProperty retrieves a Property with the given domain and property names.
    29  	//
    30  	// See: https://techdocs.akamai.com/gtm/reference/get-property
    31  	GetProperty(context.Context, string, string) (*Property, error)
    32  	// CreateProperty creates property.
    33  	//
    34  	// See: https://techdocs.akamai.com/gtm/reference/put-property
    35  	CreateProperty(context.Context, *Property, string) (*PropertyResponse, error)
    36  	// DeleteProperty is a method applied to a property object resulting in removal.
    37  	//
    38  	// See: https://techdocs.akamai.com/gtm/reference/delete-property
    39  	DeleteProperty(context.Context, *Property, string) (*ResponseStatus, error)
    40  	// UpdateProperty is a method applied to a property object resulting in an update.
    41  	//
    42  	// See: https://techdocs.akamai.com/gtm/reference/put-property
    43  	UpdateProperty(context.Context, *Property, string) (*ResponseStatus, error)
    44  }
    45  
    46  // TrafficTarget struct contains information about where to direct data center traffic
    47  type TrafficTarget struct {
    48  	DatacenterId int      `json:"datacenterId"`
    49  	Enabled      bool     `json:"enabled"`
    50  	Weight       float64  `json:"weight,omitempty"`
    51  	Servers      []string `json:"servers,omitempty"`
    52  	Name         string   `json:"name,omitempty"`
    53  	HandoutCName string   `json:"handoutCName,omitempty"`
    54  }
    55  
    56  // HttpHeader struct contains HTTP headers to send if the testObjectProtocol is http or https
    57  type HttpHeader struct {
    58  	Name  string `json:"name"`
    59  	Value string `json:"value"`
    60  }
    61  
    62  // LivenessTest contains configuration of liveness tests to determine whether your servers respond to requests
    63  type LivenessTest struct {
    64  	Name                          string        `json:"name"`
    65  	ErrorPenalty                  float64       `json:"errorPenalty,omitempty"`
    66  	PeerCertificateVerification   bool          `json:"peerCertificateVerification"`
    67  	TestInterval                  int           `json:"testInterval,omitempty"`
    68  	TestObject                    string        `json:"testObject,omitempty"`
    69  	Links                         []*Link       `json:"links,omitempty"`
    70  	RequestString                 string        `json:"requestString,omitempty"`
    71  	ResponseString                string        `json:"responseString,omitempty"`
    72  	HttpError3xx                  bool          `json:"httpError3xx"`
    73  	HttpError4xx                  bool          `json:"httpError4xx"`
    74  	HttpError5xx                  bool          `json:"httpError5xx"`
    75  	Disabled                      bool          `json:"disabled"`
    76  	TestObjectProtocol            string        `json:"testObjectProtocol,omitempty"`
    77  	TestObjectPassword            string        `json:"testObjectPassword,omitempty"`
    78  	TestObjectPort                int           `json:"testObjectPort,omitempty"`
    79  	SslClientPrivateKey           string        `json:"sslClientPrivateKey,omitempty"`
    80  	SslClientCertificate          string        `json:"sslClientCertificate,omitempty"`
    81  	DisableNonstandardPortWarning bool          `json:"disableNonstandardPortWarning"`
    82  	HttpHeaders                   []*HttpHeader `json:"httpHeaders,omitempty"`
    83  	TestObjectUsername            string        `json:"testObjectUsername,omitempty"`
    84  	TestTimeout                   float32       `json:"testTimeout,omitempty"`
    85  	TimeoutPenalty                float64       `json:"timeoutPenalty,omitempty"`
    86  	AnswersRequired               bool          `json:"answersRequired"`
    87  	ResourceType                  string        `json:"resourceType,omitempty"`
    88  	RecursionRequested            bool          `json:"recursionRequested"`
    89  }
    90  
    91  // StaticRRSet contains static recordset
    92  type StaticRRSet struct {
    93  	Type  string   `json:"type"`
    94  	TTL   int      `json:"ttl"`
    95  	Rdata []string `json:"rdata"`
    96  }
    97  
    98  // Property represents a GTM property
    99  type Property struct {
   100  	Name                      string           `json:"name"`
   101  	Type                      string           `json:"type"`
   102  	Ipv6                      bool             `json:"ipv6"`
   103  	ScoreAggregationType      string           `json:"scoreAggregationType"`
   104  	StickinessBonusPercentage int              `json:"stickinessBonusPercentage,omitempty"`
   105  	StickinessBonusConstant   int              `json:"stickinessBonusConstant,omitempty"`
   106  	HealthThreshold           float64          `json:"healthThreshold,omitempty"`
   107  	UseComputedTargets        bool             `json:"useComputedTargets"`
   108  	BackupIp                  string           `json:"backupIp,omitempty"`
   109  	BalanceByDownloadScore    bool             `json:"balanceByDownloadScore"`
   110  	StaticTTL                 int              `json:"staticTTL,omitempty"`
   111  	StaticRRSets              []*StaticRRSet   `json:"staticRRSets,omitempty"`
   112  	LastModified              string           `json:"lastModified"`
   113  	UnreachableThreshold      float64          `json:"unreachableThreshold,omitempty"`
   114  	MinLiveFraction           float64          `json:"minLiveFraction,omitempty"`
   115  	HealthMultiplier          float64          `json:"healthMultiplier,omitempty"`
   116  	DynamicTTL                int              `json:"dynamicTTL,omitempty"`
   117  	MaxUnreachablePenalty     int              `json:"maxUnreachablePenalty,omitempty"`
   118  	MapName                   string           `json:"mapName,omitempty"`
   119  	HandoutLimit              int              `json:"handoutLimit"`
   120  	HandoutMode               string           `json:"handoutMode"`
   121  	FailoverDelay             int              `json:"failoverDelay,omitempty"`
   122  	BackupCName               string           `json:"backupCName,omitempty"`
   123  	FailbackDelay             int              `json:"failbackDelay,omitempty"`
   124  	LoadImbalancePercentage   float64          `json:"loadImbalancePercentage,omitempty"`
   125  	HealthMax                 float64          `json:"healthMax,omitempty"`
   126  	GhostDemandReporting      bool             `json:"ghostDemandReporting"`
   127  	Comments                  string           `json:"comments,omitempty"`
   128  	CName                     string           `json:"cname,omitempty"`
   129  	WeightedHashBitsForIPv4   int              `json:"weightedHashBitsForIPv4,omitempty"`
   130  	WeightedHashBitsForIPv6   int              `json:"weightedHashBitsForIPv6,omitempty"`
   131  	TrafficTargets            []*TrafficTarget `json:"trafficTargets,omitempty"`
   132  	Links                     []*Link          `json:"links,omitempty"`
   133  	LivenessTests             []*LivenessTest  `json:"livenessTests,omitempty"`
   134  }
   135  
   136  // PropertyList contains a list of property items
   137  type PropertyList struct {
   138  	PropertyItems []*Property `json:"items"`
   139  }
   140  
   141  // Validate validates Property
   142  func (prop *Property) Validate() error {
   143  
   144  	if len(prop.Name) < 1 {
   145  		return fmt.Errorf("Property is missing Name")
   146  	}
   147  	if len(prop.Type) < 1 {
   148  		return fmt.Errorf("Property is missing Type")
   149  	}
   150  	if len(prop.ScoreAggregationType) < 1 {
   151  		return fmt.Errorf("Property is missing ScoreAggregationType")
   152  	}
   153  	if len(prop.HandoutMode) < 1 {
   154  		return fmt.Errorf("Property is missing HandoutMode")
   155  	}
   156  	// is zero a valid value? need to check and uncomment
   157  	//if prop.HandoutLimit == 0 {
   158  	//        return fmt.Errorf("Property is missing  handoutLimit"
   159  	//}
   160  
   161  	return nil
   162  }
   163  
   164  func (p *gtm) NewTrafficTarget(ctx context.Context) *TrafficTarget {
   165  
   166  	logger := p.Log(ctx)
   167  	logger.Debug("NewTrafficTarget")
   168  
   169  	return &TrafficTarget{}
   170  
   171  }
   172  
   173  func (p *gtm) NewStaticRRSet(ctx context.Context) *StaticRRSet {
   174  
   175  	logger := p.Log(ctx)
   176  	logger.Debug("NewStaticRRSet")
   177  
   178  	return &StaticRRSet{}
   179  
   180  }
   181  
   182  // NewHttpHeader is a method applied to a livenesstest object that instantiates an HttpHeader  object.
   183  func (lt *LivenessTest) NewHttpHeader() *HttpHeader {
   184  
   185  	return &HttpHeader{}
   186  
   187  }
   188  func (p *gtm) NewLivenessTest(ctx context.Context, name string, objproto string, interval int, timeout float32) *LivenessTest {
   189  
   190  	logger := p.Log(ctx)
   191  	logger.Debug("NewLivenessTest")
   192  
   193  	return &LivenessTest{Name: name, TestInterval: interval, TestObjectProtocol: objproto, TestTimeout: timeout}
   194  
   195  }
   196  
   197  func (p *gtm) NewProperty(ctx context.Context, name string) *Property {
   198  
   199  	logger := p.Log(ctx)
   200  	logger.Debug("NewProperty")
   201  
   202  	property := &Property{Name: name}
   203  	return property
   204  }
   205  
   206  func (p *gtm) ListProperties(ctx context.Context, domainName string) ([]*Property, error) {
   207  
   208  	logger := p.Log(ctx)
   209  	logger.Debug("ListProperties")
   210  
   211  	var properties PropertyList
   212  	getURL := fmt.Sprintf("/config-gtm/v1/domains/%s/properties", domainName)
   213  	req, err := http.NewRequestWithContext(ctx, http.MethodGet, getURL, nil)
   214  	if err != nil {
   215  		return nil, fmt.Errorf("failed to create ListProperties request: %w", err)
   216  	}
   217  	setVersionHeader(req, schemaVersion)
   218  	resp, err := p.Exec(req, &properties)
   219  	if err != nil {
   220  		return nil, fmt.Errorf("ListProperties request failed: %w", err)
   221  	}
   222  
   223  	if resp.StatusCode != http.StatusOK {
   224  		return nil, p.Error(resp)
   225  	}
   226  
   227  	return properties.PropertyItems, nil
   228  }
   229  
   230  func (p *gtm) GetProperty(ctx context.Context, name, domainName string) (*Property, error) {
   231  
   232  	logger := p.Log(ctx)
   233  	logger.Debug("GetProperty")
   234  
   235  	var property Property
   236  	getURL := fmt.Sprintf("/config-gtm/v1/domains/%s/properties/%s", domainName, name)
   237  	req, err := http.NewRequestWithContext(ctx, http.MethodGet, getURL, nil)
   238  	if err != nil {
   239  		return nil, fmt.Errorf("failed to create GetProperty request: %w", err)
   240  	}
   241  	setVersionHeader(req, schemaVersion)
   242  	resp, err := p.Exec(req, &property)
   243  	if err != nil {
   244  		return nil, fmt.Errorf("GetProperty request failed: %w", err)
   245  	}
   246  
   247  	if resp.StatusCode != http.StatusOK {
   248  		return nil, p.Error(resp)
   249  	}
   250  
   251  	return &property, nil
   252  }
   253  
   254  func (p *gtm) CreateProperty(ctx context.Context, property *Property, domainName string) (*PropertyResponse, error) {
   255  
   256  	logger := p.Log(ctx)
   257  	logger.Debug("CreateProperty")
   258  
   259  	// Need do any validation?
   260  	return property.save(ctx, p, domainName)
   261  }
   262  
   263  func (p *gtm) UpdateProperty(ctx context.Context, property *Property, domainName string) (*ResponseStatus, error) {
   264  
   265  	logger := p.Log(ctx)
   266  	logger.Debug("UpdateProperty")
   267  
   268  	// Need do any validation?
   269  	stat, err := property.save(ctx, p, domainName)
   270  	if err != nil {
   271  		return nil, err
   272  	}
   273  	return stat.Status, err
   274  
   275  }
   276  
   277  // Save Property updates method
   278  func (prop *Property) save(ctx context.Context, p *gtm, domainName string) (*PropertyResponse, error) {
   279  
   280  	if err := prop.Validate(); err != nil {
   281  		return nil, fmt.Errorf("Property validation failed. %w", err)
   282  	}
   283  
   284  	putURL := fmt.Sprintf("/config-gtm/v1/domains/%s/properties/%s", domainName, prop.Name)
   285  	req, err := http.NewRequestWithContext(ctx, http.MethodPut, putURL, nil)
   286  	if err != nil {
   287  		return nil, fmt.Errorf("failed to create Property request: %w", err)
   288  	}
   289  
   290  	var presp PropertyResponse
   291  	setVersionHeader(req, schemaVersion)
   292  	resp, err := p.Exec(req, &presp, prop)
   293  	if err != nil {
   294  		return nil, fmt.Errorf("Property request failed: %w", err)
   295  	}
   296  
   297  	if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated {
   298  		return nil, p.Error(resp)
   299  	}
   300  
   301  	return &presp, nil
   302  }
   303  
   304  func (p *gtm) DeleteProperty(ctx context.Context, property *Property, domainName string) (*ResponseStatus, error) {
   305  
   306  	logger := p.Log(ctx)
   307  	logger.Debug("DeleteProperty")
   308  
   309  	if err := property.Validate(); err != nil {
   310  		logger.Errorf("Property validation failed. %w", err)
   311  		return nil, fmt.Errorf("Property validation failed. %w", err)
   312  	}
   313  
   314  	delURL := fmt.Sprintf("/config-gtm/v1/domains/%s/properties/%s", domainName, property.Name)
   315  	req, err := http.NewRequestWithContext(ctx, http.MethodDelete, delURL, nil)
   316  	if err != nil {
   317  		return nil, fmt.Errorf("failed to create Property request: %w", err)
   318  	}
   319  
   320  	var presp ResponseBody
   321  	setVersionHeader(req, schemaVersion)
   322  	resp, err := p.Exec(req, &presp)
   323  	if err != nil {
   324  		return nil, fmt.Errorf("Property request failed: %w", err)
   325  	}
   326  
   327  	if resp.StatusCode != http.StatusOK {
   328  		return nil, p.Error(resp)
   329  	}
   330  
   331  	return presp.Status, nil
   332  }