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 }