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