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

     1  package papi
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  	"net/http"
     8  	"strings"
     9  
    10  	"github.com/akamai/AkamaiOPEN-edgegrid-golang/v2/pkg/edgegriderr"
    11  	validation "github.com/go-ozzo/ozzo-validation/v4"
    12  )
    13  
    14  type (
    15  	// EdgeHostnames contains operations available on EdgeHostnames resource
    16  	// See: https://developer.akamai.com/api/core_features/property_manager/v1.html#edgehostnamesgroup
    17  	EdgeHostnames interface {
    18  		// GetEdgeHostnames fetches a list of edge hostnames
    19  		// See: https://developer.akamai.com/api/core_features/property_manager/v1.html#getedgehostnames
    20  		GetEdgeHostnames(context.Context, GetEdgeHostnamesRequest) (*GetEdgeHostnamesResponse, error)
    21  
    22  		// GetEdgeHostname fetches edge hostname with given ID
    23  		// See: https://developer.akamai.com/api/core_features/property_manager/v1.html#getedgehostname
    24  		GetEdgeHostname(context.Context, GetEdgeHostnameRequest) (*GetEdgeHostnamesResponse, error)
    25  
    26  		// CreateEdgeHostname creates a new edge hostname
    27  		// See: https://developer.akamai.com/api/core_features/property_manager/v1.html#postedgehostnames
    28  		CreateEdgeHostname(context.Context, CreateEdgeHostnameRequest) (*CreateEdgeHostnameResponse, error)
    29  	}
    30  
    31  	// GetEdgeHostnamesRequest contains query params used for listing edge hostnames
    32  	GetEdgeHostnamesRequest struct {
    33  		ContractID string
    34  		GroupID    string
    35  		Options    []string
    36  	}
    37  
    38  	// GetEdgeHostnameRequest contains path and query params used to fetch specific edge hostname
    39  	GetEdgeHostnameRequest struct {
    40  		EdgeHostnameID string
    41  		ContractID     string
    42  		GroupID        string
    43  		Options        []string
    44  	}
    45  
    46  	// GetEdgeHostnamesResponse contains data received by calling GetEdgeHostnames or GetEdgeHostname
    47  	GetEdgeHostnamesResponse struct {
    48  		AccountID     string            `json:"accountId"`
    49  		ContractID    string            `json:"contractId"`
    50  		GroupID       string            `json:"groupId"`
    51  		EdgeHostnames EdgeHostnameItems `json:"edgeHostnames"`
    52  		EdgeHostname  EdgeHostnameGetItem
    53  	}
    54  
    55  	// EdgeHostnameItems contains a list of EdgeHostnames
    56  	EdgeHostnameItems struct {
    57  		Items []EdgeHostnameGetItem `json:"items"`
    58  	}
    59  
    60  	// EdgeHostnameGetItem contains GET details for edge hostname
    61  	EdgeHostnameGetItem struct {
    62  		ID                string    `json:"edgeHostnameId"`
    63  		Domain            string    `json:"edgeHostnameDomain"`
    64  		ProductID         string    `json:"productId"`
    65  		DomainPrefix      string    `json:"domainPrefix"`
    66  		DomainSuffix      string    `json:"domainSuffix"`
    67  		Status            string    `json:"status,omitempty"`
    68  		Secure            bool      `json:"secure"`
    69  		IPVersionBehavior string    `json:"ipVersionBehavior"`
    70  		UseCases          []UseCase `json:"useCases,omitempty"`
    71  	}
    72  
    73  	// UseCase contains UseCase data
    74  	UseCase struct {
    75  		Option  string `json:"option"`
    76  		Type    string `json:"type"`
    77  		UseCase string `json:"useCase"`
    78  	}
    79  
    80  	// CreateEdgeHostnameRequest contains query params and body required for creation of new edge hostname
    81  	CreateEdgeHostnameRequest struct {
    82  		ContractID   string
    83  		GroupID      string
    84  		Options      []string
    85  		EdgeHostname EdgeHostnameCreate
    86  	}
    87  
    88  	// EdgeHostnameCreate contains body of edge hostname POST request
    89  	EdgeHostnameCreate struct {
    90  		ProductID         string    `json:"productId"`
    91  		DomainPrefix      string    `json:"domainPrefix"`
    92  		DomainSuffix      string    `json:"domainSuffix"`
    93  		Secure            bool      `json:"secure,omitempty"`
    94  		SecureNetwork     string    `json:"secureNetwork,omitempty"`
    95  		SlotNumber        int       `json:"slotNumber,omitempty"`
    96  		IPVersionBehavior string    `json:"ipVersionBehavior"`
    97  		CertEnrollmentID  int       `json:"certEnrollmentId,omitempty"`
    98  		UseCases          []UseCase `json:"useCases,omitempty"`
    99  	}
   100  
   101  	// CreateEdgeHostnameResponse contains a link returned after creating new edge hostname and DI of this hostname
   102  	CreateEdgeHostnameResponse struct {
   103  		EdgeHostnameLink string `json:"edgeHostnameLink"`
   104  		EdgeHostnameID   string `json:"-"`
   105  	}
   106  )
   107  
   108  const (
   109  	// EHSecureNetworkStandardTLS constant
   110  	EHSecureNetworkStandardTLS = "STANDARD_TLS"
   111  	// EHSecureNetworkSharedCert constant
   112  	EHSecureNetworkSharedCert = "SHARED_CERT"
   113  	// EHSecureNetworkEnhancedTLS constant
   114  	EHSecureNetworkEnhancedTLS = "ENHANCED_TLS"
   115  
   116  	// EHIPVersionV4 constant
   117  	EHIPVersionV4 = "IPV4"
   118  	// EHIPVersionV6Performance constant
   119  	EHIPVersionV6Performance = "IPV6_PERFORMANCE"
   120  	// EHIPVersionV6Compliance constant
   121  	EHIPVersionV6Compliance = "IPV6_COMPLIANCE"
   122  
   123  	// UseCaseGlobal constant
   124  	UseCaseGlobal = "GLOBAL"
   125  )
   126  
   127  // Validate validates CreateEdgeHostnameRequest
   128  func (eh CreateEdgeHostnameRequest) Validate() error {
   129  	errs := validation.Errors{
   130  		"ContractID":   validation.Validate(eh.ContractID, validation.Required),
   131  		"GroupID":      validation.Validate(eh.GroupID, validation.Required),
   132  		"EdgeHostname": validation.Validate(eh.EdgeHostname),
   133  	}
   134  	return edgegriderr.ParseValidationErrors(errs)
   135  }
   136  
   137  // Validate validates EdgeHostnameCreate
   138  func (eh EdgeHostnameCreate) Validate() error {
   139  	return validation.Errors{
   140  		"DomainPrefix": validation.Validate(eh.DomainPrefix, validation.Required),
   141  		"DomainSuffix": validation.Validate(eh.DomainSuffix, validation.Required,
   142  			validation.When(eh.SecureNetwork == EHSecureNetworkStandardTLS, validation.In("edgesuite.net")),
   143  			validation.When(eh.SecureNetwork == EHSecureNetworkSharedCert, validation.In("akamaized.net")),
   144  			validation.When(eh.SecureNetwork == EHSecureNetworkEnhancedTLS, validation.In("edgekey.net")),
   145  		),
   146  		"ProductID":         validation.Validate(eh.ProductID, validation.Required),
   147  		"CertEnrollmentID":  validation.Validate(eh.CertEnrollmentID, validation.Required.When(eh.SecureNetwork == EHSecureNetworkEnhancedTLS)),
   148  		"IPVersionBehavior": validation.Validate(eh.IPVersionBehavior, validation.Required, validation.In(EHIPVersionV4, EHIPVersionV6Performance, EHIPVersionV6Compliance)),
   149  		"SecureNetwork":     validation.Validate(eh.SecureNetwork, validation.In(EHSecureNetworkStandardTLS, EHSecureNetworkSharedCert, EHSecureNetworkEnhancedTLS)),
   150  		"UseCases":          validation.Validate(eh.UseCases),
   151  	}.Filter()
   152  }
   153  
   154  // Validate validates UseCase
   155  func (uc UseCase) Validate() error {
   156  	return validation.Errors{
   157  		"Option":  validation.Validate(uc.Option, validation.Required),
   158  		"Type":    validation.Validate(uc.Type, validation.Required, validation.In(UseCaseGlobal)),
   159  		"UseCase": validation.Validate(uc.UseCase, validation.Required),
   160  	}.Filter()
   161  }
   162  
   163  // Validate validates GetEdgeHostnamesRequest
   164  func (eh GetEdgeHostnamesRequest) Validate() error {
   165  	return validation.Errors{
   166  		"ContractID": validation.Validate(eh.ContractID, validation.Required),
   167  		"GroupID":    validation.Validate(eh.GroupID, validation.Required),
   168  	}.Filter()
   169  }
   170  
   171  // Validate validates GetEdgeHostnameRequest
   172  func (eh GetEdgeHostnameRequest) Validate() error {
   173  	return validation.Errors{
   174  		"EdgeHostnameID": validation.Validate(eh.EdgeHostnameID, validation.Required),
   175  		"ContractID":     validation.Validate(eh.ContractID, validation.Required),
   176  		"GroupID":        validation.Validate(eh.GroupID, validation.Required),
   177  	}.Filter()
   178  }
   179  
   180  var (
   181  	// ErrGetEdgeHostnames represents error when fetching edge hostnames fails
   182  	ErrGetEdgeHostnames = errors.New("fetching edge hostnames")
   183  	// ErrGetEdgeHostname represents error when fetching edge hostname fails
   184  	ErrGetEdgeHostname = errors.New("fetching edge hostname")
   185  	// ErrCreateEdgeHostname represents error when creating edge hostname fails
   186  	ErrCreateEdgeHostname = errors.New("creating edge hostname")
   187  )
   188  
   189  // GetEdgeHostnames id used to list edge hostnames for provided group and contract IDs
   190  func (p *papi) GetEdgeHostnames(ctx context.Context, params GetEdgeHostnamesRequest) (*GetEdgeHostnamesResponse, error) {
   191  	if err := params.Validate(); err != nil {
   192  		return nil, fmt.Errorf("%s: %w: %s", ErrGetEdgeHostnames, ErrStructValidation, err)
   193  	}
   194  
   195  	logger := p.Log(ctx)
   196  	logger.Debug("GetEdgeHostnames")
   197  
   198  	getURL := fmt.Sprintf(
   199  		"/papi/v1/edgehostnames?contractId=%s&groupId=%s",
   200  		params.ContractID,
   201  		params.GroupID,
   202  	)
   203  	if len(params.Options) > 0 {
   204  		getURL = fmt.Sprintf("%s&options=%s", getURL, strings.Join(params.Options, ","))
   205  	}
   206  	req, err := http.NewRequestWithContext(ctx, http.MethodGet, getURL, nil)
   207  	if err != nil {
   208  		return nil, fmt.Errorf("%w: failed to create request: %s", ErrGetEdgeHostnames, err)
   209  	}
   210  
   211  	var edgeHostnames GetEdgeHostnamesResponse
   212  	resp, err := p.Exec(req, &edgeHostnames)
   213  	if err != nil {
   214  		return nil, fmt.Errorf("%w: request failed: %s", ErrGetEdgeHostnames, err)
   215  	}
   216  
   217  	if resp.StatusCode != http.StatusOK {
   218  		return nil, fmt.Errorf("%s: %w", ErrGetEdgeHostnames, p.Error(resp))
   219  	}
   220  
   221  	return &edgeHostnames, nil
   222  }
   223  
   224  // GetEdgeHostname id used to fetch edge hostname with given ID for provided group and contract IDs
   225  func (p *papi) GetEdgeHostname(ctx context.Context, params GetEdgeHostnameRequest) (*GetEdgeHostnamesResponse, error) {
   226  	if err := params.Validate(); err != nil {
   227  		return nil, fmt.Errorf("%s: %w: %s", ErrGetEdgeHostname, ErrStructValidation, err)
   228  	}
   229  
   230  	logger := p.Log(ctx)
   231  	logger.Debug("GetEdgeHostname")
   232  
   233  	getURL := fmt.Sprintf(
   234  		"/papi/v1/edgehostnames/%s?contractId=%s&groupId=%s",
   235  		params.EdgeHostnameID,
   236  		params.ContractID,
   237  		params.GroupID,
   238  	)
   239  	if len(params.Options) > 0 {
   240  		getURL = fmt.Sprintf("%s&options=%s", getURL, strings.Join(params.Options, ","))
   241  	}
   242  	req, err := http.NewRequestWithContext(ctx, http.MethodGet, getURL, nil)
   243  	if err != nil {
   244  		return nil, fmt.Errorf("%w: failed to create request: %s", ErrGetEdgeHostname, err)
   245  	}
   246  
   247  	var edgeHostname GetEdgeHostnamesResponse
   248  	resp, err := p.Exec(req, &edgeHostname)
   249  	if err != nil {
   250  		return nil, fmt.Errorf("%w: request failed: %s", ErrGetEdgeHostname, err)
   251  	}
   252  
   253  	if resp.StatusCode != http.StatusOK {
   254  		return nil, p.Error(resp)
   255  	}
   256  	if len(edgeHostname.EdgeHostnames.Items) == 0 {
   257  		return nil, fmt.Errorf("%s: %w: EdgeHostnameID: %s", ErrGetEdgeHostname, ErrNotFound, params.EdgeHostnameID)
   258  	}
   259  	edgeHostname.EdgeHostname = edgeHostname.EdgeHostnames.Items[0]
   260  
   261  	return &edgeHostname, nil
   262  }
   263  
   264  // CreateEdgeHostname id used to create new edge hostname for provided group and contract IDs
   265  func (p *papi) CreateEdgeHostname(ctx context.Context, r CreateEdgeHostnameRequest) (*CreateEdgeHostnameResponse, error) {
   266  	if err := r.Validate(); err != nil {
   267  		return nil, fmt.Errorf("%s: %w:\n%s", ErrCreateEdgeHostname, ErrStructValidation, err)
   268  	}
   269  
   270  	logger := p.Log(ctx)
   271  	logger.Debug("CreateEdgeHostname")
   272  
   273  	createURL := fmt.Sprintf(
   274  		"/papi/v1/edgehostnames?contractId=%s&groupId=%s",
   275  		r.ContractID,
   276  		r.GroupID,
   277  	)
   278  	if len(r.Options) > 0 {
   279  		createURL = fmt.Sprintf("%s&options=%s", createURL, strings.Join(r.Options, ","))
   280  	}
   281  	req, err := http.NewRequestWithContext(ctx, http.MethodPost, createURL, nil)
   282  	if err != nil {
   283  		return nil, fmt.Errorf("%w: failed to create request: %s", ErrCreateEdgeHostname, err)
   284  	}
   285  
   286  	var createResponse CreateEdgeHostnameResponse
   287  	resp, err := p.Exec(req, &createResponse, r.EdgeHostname)
   288  	if err != nil {
   289  		return nil, fmt.Errorf("%w: request failed: %s", ErrCreateEdgeHostname, err)
   290  	}
   291  	if resp.StatusCode != http.StatusCreated {
   292  		return nil, fmt.Errorf("%s: %w", ErrCreateEdgeHostname, p.Error(resp))
   293  	}
   294  	id, err := ResponseLinkParse(createResponse.EdgeHostnameLink)
   295  	if err != nil {
   296  		return nil, fmt.Errorf("%s: %w: %s", ErrCreateEdgeHostname, ErrInvalidResponseLink, err)
   297  	}
   298  	createResponse.EdgeHostnameID = id
   299  	return &createResponse, nil
   300  }