1package cloudflare 2 3import ( 4 "context" 5 "encoding/json" 6 "fmt" 7 "net/http" 8 "time" 9 10 "github.com/pkg/errors" 11) 12 13// ZoneCustomSSL represents custom SSL certificate metadata. 14type ZoneCustomSSL struct { 15 ID string `json:"id"` 16 Hosts []string `json:"hosts"` 17 Issuer string `json:"issuer"` 18 Signature string `json:"signature"` 19 Status string `json:"status"` 20 BundleMethod string `json:"bundle_method"` 21 GeoRestrictions ZoneCustomSSLGeoRestrictions `json:"geo_restrictions"` 22 ZoneID string `json:"zone_id"` 23 UploadedOn time.Time `json:"uploaded_on"` 24 ModifiedOn time.Time `json:"modified_on"` 25 ExpiresOn time.Time `json:"expires_on"` 26 Priority int `json:"priority"` 27 KeylessServer KeylessSSL `json:"keyless_server"` 28} 29 30// ZoneCustomSSLGeoRestrictions represents the parameter to create or update 31// geographic restrictions on a custom ssl certificate. 32type ZoneCustomSSLGeoRestrictions struct { 33 Label string `json:"label"` 34} 35 36// zoneCustomSSLResponse represents the response from the zone SSL details endpoint. 37type zoneCustomSSLResponse struct { 38 Response 39 Result ZoneCustomSSL `json:"result"` 40} 41 42// zoneCustomSSLsResponse represents the response from the zone SSL list endpoint. 43type zoneCustomSSLsResponse struct { 44 Response 45 Result []ZoneCustomSSL `json:"result"` 46} 47 48// ZoneCustomSSLOptions represents the parameters to create or update an existing 49// custom SSL configuration. 50type ZoneCustomSSLOptions struct { 51 Certificate string `json:"certificate"` 52 PrivateKey string `json:"private_key"` 53 BundleMethod string `json:"bundle_method,omitempty"` 54 GeoRestrictions *ZoneCustomSSLGeoRestrictions `json:"geo_restrictions,omitempty"` 55 Type string `json:"type,omitempty"` 56} 57 58// ZoneCustomSSLPriority represents a certificate's ID and priority. It is a 59// subset of ZoneCustomSSL used for patch requests. 60type ZoneCustomSSLPriority struct { 61 ID string `json:"ID"` 62 Priority int `json:"priority"` 63} 64 65// CreateSSL allows you to add a custom SSL certificate to the given zone. 66// 67// API reference: https://api.cloudflare.com/#custom-ssl-for-a-zone-create-ssl-configuration 68func (api *API) CreateSSL(ctx context.Context, zoneID string, options ZoneCustomSSLOptions) (ZoneCustomSSL, error) { 69 uri := fmt.Sprintf("/zones/%s/custom_certificates", zoneID) 70 res, err := api.makeRequestContext(ctx, http.MethodPost, uri, options) 71 if err != nil { 72 return ZoneCustomSSL{}, err 73 } 74 var r zoneCustomSSLResponse 75 if err := json.Unmarshal(res, &r); err != nil { 76 return ZoneCustomSSL{}, errors.Wrap(err, errUnmarshalError) 77 } 78 return r.Result, nil 79} 80 81// ListSSL lists the custom certificates for the given zone. 82// 83// API reference: https://api.cloudflare.com/#custom-ssl-for-a-zone-list-ssl-configurations 84func (api *API) ListSSL(ctx context.Context, zoneID string) ([]ZoneCustomSSL, error) { 85 uri := fmt.Sprintf("/zones/%s/custom_certificates", zoneID) 86 res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil) 87 if err != nil { 88 return nil, err 89 } 90 var r zoneCustomSSLsResponse 91 if err := json.Unmarshal(res, &r); err != nil { 92 return nil, errors.Wrap(err, errUnmarshalError) 93 } 94 return r.Result, nil 95} 96 97// SSLDetails returns the configuration details for a custom SSL certificate. 98// 99// API reference: https://api.cloudflare.com/#custom-ssl-for-a-zone-ssl-configuration-details 100func (api *API) SSLDetails(ctx context.Context, zoneID, certificateID string) (ZoneCustomSSL, error) { 101 uri := fmt.Sprintf("/zones/%s/custom_certificates/%s", zoneID, certificateID) 102 res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil) 103 if err != nil { 104 return ZoneCustomSSL{}, err 105 } 106 var r zoneCustomSSLResponse 107 if err := json.Unmarshal(res, &r); err != nil { 108 return ZoneCustomSSL{}, errors.Wrap(err, errUnmarshalError) 109 } 110 return r.Result, nil 111} 112 113// UpdateSSL updates (replaces) a custom SSL certificate. 114// 115// API reference: https://api.cloudflare.com/#custom-ssl-for-a-zone-update-ssl-configuration 116func (api *API) UpdateSSL(ctx context.Context, zoneID, certificateID string, options ZoneCustomSSLOptions) (ZoneCustomSSL, error) { 117 uri := fmt.Sprintf("/zones/%s/custom_certificates/%s", zoneID, certificateID) 118 res, err := api.makeRequestContext(ctx, http.MethodPatch, uri, options) 119 if err != nil { 120 return ZoneCustomSSL{}, err 121 } 122 var r zoneCustomSSLResponse 123 if err := json.Unmarshal(res, &r); err != nil { 124 return ZoneCustomSSL{}, errors.Wrap(err, errUnmarshalError) 125 } 126 return r.Result, nil 127} 128 129// ReprioritizeSSL allows you to change the priority (which is served for a given 130// request) of custom SSL certificates associated with the given zone. 131// 132// API reference: https://api.cloudflare.com/#custom-ssl-for-a-zone-re-prioritize-ssl-certificates 133func (api *API) ReprioritizeSSL(ctx context.Context, zoneID string, p []ZoneCustomSSLPriority) ([]ZoneCustomSSL, error) { 134 uri := fmt.Sprintf("/zones/%s/custom_certificates/prioritize", zoneID) 135 params := struct { 136 Certificates []ZoneCustomSSLPriority `json:"certificates"` 137 }{ 138 Certificates: p, 139 } 140 res, err := api.makeRequestContext(ctx, http.MethodPut, uri, params) 141 if err != nil { 142 return nil, err 143 } 144 var r zoneCustomSSLsResponse 145 if err := json.Unmarshal(res, &r); err != nil { 146 return nil, errors.Wrap(err, errUnmarshalError) 147 } 148 return r.Result, nil 149} 150 151// DeleteSSL deletes a custom SSL certificate from the given zone. 152// 153// API reference: https://api.cloudflare.com/#custom-ssl-for-a-zone-delete-an-ssl-certificate 154func (api *API) DeleteSSL(ctx context.Context, zoneID, certificateID string) error { 155 uri := fmt.Sprintf("/zones/%s/custom_certificates/%s", zoneID, certificateID) 156 if _, err := api.makeRequestContext(ctx, http.MethodDelete, uri, nil); err != nil { 157 return err 158 } 159 return nil 160} 161