github.com/akamai/AkamaiOPEN-edgegrid-golang/v8@v8.1.0/pkg/cps/change_management_info.go (about) 1 package cps 2 3 import ( 4 "context" 5 "errors" 6 "fmt" 7 "net/http" 8 ) 9 10 type ( 11 // ChangeManagementInfo is a CPS API enabling change management 12 ChangeManagementInfo interface { 13 // GetChangeManagementInfo gets information about acknowledgement status, 14 // and may include warnings about potential conflicts that may occur if you proceed with acknowledgement 15 // 16 // See: https://techdocs.akamai.com/cps/reference/get-change-allowed-input-param 17 GetChangeManagementInfo(ctx context.Context, params GetChangeRequest) (*ChangeManagementInfoResponse, error) 18 19 // GetChangeDeploymentInfo gets deployment currently deployed to the staging network 20 // 21 // See: https://techdocs.akamai.com/cps/reference/get-change-allowed-input-param 22 GetChangeDeploymentInfo(ctx context.Context, params GetChangeRequest) (*ChangeDeploymentInfoResponse, error) 23 24 // AcknowledgeChangeManagement sends acknowledgement request to CPS to proceed deploying the certificate to the production network 25 // 26 // See: https://techdocs.akamai.com/cps/reference/post-change-allowed-input-param 27 AcknowledgeChangeManagement(context.Context, AcknowledgementRequest) error 28 } 29 30 // ChangeManagementInfoResponse contains response from GetChangeManagementInfo 31 ChangeManagementInfoResponse struct { 32 AcknowledgementDeadline *string `json:"acknowledgementDeadline"` 33 ValidationResultHash string `json:"validationResultHash"` 34 PendingState PendingState `json:"pendingState"` 35 ValidationResult *ValidationResult `json:"validationResult"` 36 } 37 38 // PendingState contains the snapshot of the pending state for the enrollment 39 PendingState struct { 40 PendingCertificates []PendingCertificate `json:"pendingCertificates"` 41 PendingNetworkConfiguration PendingNetworkConfiguration `json:"pendingNetworkConfiguration"` 42 } 43 44 // PendingCertificate contains the snapshot of the pending certificate for the enrollment 45 PendingCertificate struct { 46 CertificateType string `json:"certificateType"` 47 FullCertificate string `json:"fullCertificate"` 48 OCSPStapled string `json:"ocspStapled"` 49 OCSPURIs []string `json:"ocspUris"` 50 SignatureAlgorithm string `json:"signatureAlgorithm"` 51 KeyAlgorithm string `json:"keyAlgorithm"` 52 } 53 54 // PendingNetworkConfiguration contains the snapshot of the pending network configuration for the enrollment 55 PendingNetworkConfiguration struct { 56 DNSNameSettings *DNSNameSettings `json:"dnsNameSettings"` 57 MustHaveCiphers string `json:"mustHaveCiphers"` 58 NetworkType string `json:"networkType"` 59 OCSPStapling string `json:"ocspStapling"` 60 PreferredCiphers string `json:"preferredCiphers"` 61 QUICEnabled string `json:"quicEnabled"` 62 SNIOnly string `json:"sniOnly"` 63 DisallowedTLSVersions []string `json:"disallowedTlsVersions"` 64 } 65 66 // ValidationResult contains validation errors and warnings messages 67 ValidationResult struct { 68 Errors []ValidationMessage `json:"errors"` 69 Warnings []ValidationMessage `json:"warnings"` 70 } 71 72 // ValidationMessage holds validation message 73 ValidationMessage struct { 74 Message string `json:"message"` 75 MessageCode string `json:"messageCode"` 76 } 77 78 // ChangeDeploymentInfoResponse contains response from GetChangeDeploymentInfo 79 ChangeDeploymentInfoResponse Deployment 80 ) 81 82 var ( 83 // ErrGetChangeManagementInfo is returned when GetChangeManagementInfo fails 84 ErrGetChangeManagementInfo = errors.New("get change management info") 85 // ErrGetChangeDeploymentInfo is returned when GetChangeDeploymentInfo fails 86 ErrGetChangeDeploymentInfo = errors.New("get change deployment info") 87 // ErrAcknowledgeChangeManagement is returned when AcknowledgeChangeManagement fails 88 ErrAcknowledgeChangeManagement = errors.New("acknowledging change management") 89 ) 90 91 func (c *cps) GetChangeManagementInfo(ctx context.Context, params GetChangeRequest) (*ChangeManagementInfoResponse, error) { 92 c.Log(ctx).Debug("GetChangeManagementInfo") 93 94 if err := params.Validate(); err != nil { 95 return nil, fmt.Errorf("%s: %w: %s", ErrGetChangeManagementInfo, ErrStructValidation, err) 96 } 97 98 uri := fmt.Sprintf("/cps/v2/enrollments/%d/changes/%d/input/info/change-management-info", 99 params.EnrollmentID, params.ChangeID) 100 101 req, err := http.NewRequestWithContext(ctx, http.MethodGet, uri, nil) 102 if err != nil { 103 return nil, fmt.Errorf("%w: failed to create request: %s", ErrGetChangeManagementInfo, err) 104 } 105 req.Header.Set("Accept", "application/vnd.akamai.cps.change-management-info.v5+json") 106 107 var result ChangeManagementInfoResponse 108 resp, err := c.Exec(req, &result) 109 if err != nil { 110 return nil, fmt.Errorf("%w: request failed: %s", ErrGetChangeManagementInfo, err) 111 } 112 113 if resp.StatusCode != http.StatusOK { 114 return nil, fmt.Errorf("%s: %w", ErrGetChangeManagementInfo, c.Error(resp)) 115 } 116 117 return &result, nil 118 } 119 120 func (c *cps) GetChangeDeploymentInfo(ctx context.Context, params GetChangeRequest) (*ChangeDeploymentInfoResponse, error) { 121 c.Log(ctx).Debug("GetChangeDeploymentInfo") 122 123 if err := params.Validate(); err != nil { 124 return nil, fmt.Errorf("%s: %w: %s", ErrGetChangeDeploymentInfo, ErrStructValidation, err) 125 } 126 127 uri := fmt.Sprintf("/cps/v2/enrollments/%d/changes/%d/input/info/change-management-info", 128 params.EnrollmentID, params.ChangeID) 129 130 req, err := http.NewRequestWithContext(ctx, http.MethodGet, uri, nil) 131 if err != nil { 132 return nil, fmt.Errorf("%w: failed to create request: %s", ErrGetChangeDeploymentInfo, err) 133 } 134 req.Header.Set("Accept", "application/vnd.akamai.cps.deployment.v8+json") 135 136 var result ChangeDeploymentInfoResponse 137 resp, err := c.Exec(req, &result) 138 if err != nil { 139 return nil, fmt.Errorf("%w: request failed: %s", ErrGetChangeDeploymentInfo, err) 140 } 141 142 if resp.StatusCode != http.StatusOK { 143 return nil, fmt.Errorf("%s: %w", ErrGetChangeDeploymentInfo, c.Error(resp)) 144 } 145 146 return &result, nil 147 } 148 149 func (c *cps) AcknowledgeChangeManagement(ctx context.Context, params AcknowledgementRequest) error { 150 c.Log(ctx).Debug("AcknowledgeChangeManagement") 151 152 if err := params.Validate(); err != nil { 153 return fmt.Errorf("%s: %w: %s", ErrAcknowledgeChangeManagement, ErrStructValidation, err) 154 } 155 156 uri := fmt.Sprintf("/cps/v2/enrollments/%d/changes/%d/input/update/change-management-ack", 157 params.EnrollmentID, params.ChangeID) 158 159 req, err := http.NewRequestWithContext(ctx, http.MethodPost, uri, nil) 160 if err != nil { 161 return fmt.Errorf("%w: failed to create request: %s", ErrAcknowledgeChangeManagement, err) 162 } 163 req.Header.Set("Accept", "application/vnd.akamai.cps.change-id.v1+json") 164 req.Header.Set("Content-Type", "application/vnd.akamai.cps.acknowledgement.v1+json; charset=utf-8") 165 166 resp, err := c.Exec(req, nil, params.Acknowledgement) 167 if err != nil { 168 return fmt.Errorf("%w: request failed: %s", ErrAcknowledgeChangeManagement, err) 169 } 170 171 if resp.StatusCode != http.StatusOK { 172 return fmt.Errorf("%s: %w", ErrAcknowledgeChangeManagement, c.Error(resp)) 173 } 174 175 return nil 176 }