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 }