github.com/akamai/AkamaiOPEN-edgegrid-golang/v8@v8.1.0/pkg/appsec/tuning_recommendations.go (about) 1 package appsec 2 3 import ( 4 "context" 5 "fmt" 6 "net/http" 7 "time" 8 9 validation "github.com/go-ozzo/ozzo-validation/v4" 10 ) 11 12 type ( 13 // The TuningRecommendations interface supports retrieving tuning recommendations for a security policy, a specific attack group or a rule 14 TuningRecommendations interface { 15 // GetTuningRecommendations lists available tuning recommendations for a policy. 16 // 17 // See: https://techdocs.akamai.com/application-security/reference/get-recommendations 18 GetTuningRecommendations(ctx context.Context, params GetTuningRecommendationsRequest) (*GetTuningRecommendationsResponse, error) 19 20 // GetAttackGroupRecommendations returns available tuning recommendations for an attack group. 21 // 22 // See: https://techdocs.akamai.com/application-security/reference/get-attack-group 23 GetAttackGroupRecommendations(ctx context.Context, params GetAttackGroupRecommendationsRequest) (*GetAttackGroupRecommendationsResponse, error) 24 25 // GetRuleRecommendations returns available tuning recommendations for a rule. 26 // 27 // See: https://techdocs.akamai.com/application-security/reference/get-recommendations-rule 28 GetRuleRecommendations(ctx context.Context, params GetRuleRecommendationsRequest) (*GetRuleRecommendationsResponse, error) 29 } 30 31 // GetTuningRecommendationsRequest is used to retrieve tuning recommendations for a security policy. 32 GetTuningRecommendationsRequest struct { 33 ConfigID int 34 Version int 35 PolicyID string 36 RulesetType RulesetType 37 } 38 39 // GetAttackGroupRecommendationsRequest is used to retrieve tuning recommendations for a specific attack group. 40 GetAttackGroupRecommendationsRequest struct { 41 ConfigID int 42 Version int 43 PolicyID string 44 Group string 45 RulesetType RulesetType 46 } 47 48 // GetRuleRecommendationsRequest is used to retrieve tuning recommendations for a specific rule. 49 GetRuleRecommendationsRequest struct { 50 ConfigID int 51 Version int 52 PolicyID string 53 RuleID int 54 RulesetType RulesetType 55 } 56 57 // GetTuningRecommendationsResponse is returned from a call to GetTuningRecommendations. 58 GetTuningRecommendationsResponse struct { 59 AttackGroupRecommendations []AttackGroupRecommendation `json:"attackGroupRecommendations,omitempty"` 60 RuleRecommendations []RuleRecommendation `json:"ruleRecommendations,omitempty"` 61 EvaluationPeriodStart time.Time `json:"evaluationPeriodStart,omitempty"` 62 EvaluationPeriodEnd time.Time `json:"evaluationPeriodEnd,omitempty"` 63 } 64 65 // GetAttackGroupRecommendationsResponse is returned from a call to GetAttackGroupRecommendations. 66 GetAttackGroupRecommendationsResponse AttackGroupRecommendation 67 68 // GetRuleRecommendationsResponse is returned from a call to GetRuleRecommendations. 69 GetRuleRecommendationsResponse RuleRecommendation 70 71 // AttackGroupRecommendation is used to describe a recommendation for an attack group. 72 AttackGroupRecommendation struct { 73 Description string `json:"description,omitempty"` 74 Evidence *Evidences `json:"evidences,omitempty"` 75 Exception *AttackGroupException `json:"exception,omitempty"` 76 Group string `json:"group,omitempty"` 77 } 78 // RuleRecommendation is used to describe a recommendation for a rule. 79 RuleRecommendation struct { 80 Description string `json:"description,omitempty"` 81 Evidence *Evidences `json:"evidences,omitempty"` 82 Exception *AttackGroupException `json:"exception,omitempty"` 83 RuleId int `json:"ruleId,omitempty"` 84 } 85 86 // Evidences is used to describe evidences for a recommendation. 87 Evidences []struct { 88 HostEvidences []string `json:"hostEvidences,omitempty"` 89 PathEvidences []string `json:"pathEvidences,omitempty"` 90 UserDataEvidences []string `json:"userDataEvidences,omitempty"` 91 } 92 ) 93 94 // Validate validates a GetTuningRecommendationsRequest. 95 func (v GetTuningRecommendationsRequest) Validate() error { 96 return validation.Errors{ 97 "ConfigID": validation.Validate(v.ConfigID, validation.Required), 98 "Version": validation.Validate(v.Version, validation.Required), 99 "PolicyID": validation.Validate(v.PolicyID, validation.Required), 100 "RulesetType": validation.Validate(v.RulesetType, validation.In(RulesetTypeActive, RulesetTypeEvaluation).Error( 101 fmt.Sprintf("value '%s' is invalid. Must be one of: 'active', 'evaluation' or '' (empty)", v.RulesetType))), 102 }.Filter() 103 } 104 105 // Validate validates a GetAttackGroupRecommendationsRequest. 106 func (v GetAttackGroupRecommendationsRequest) Validate() error { 107 return validation.Errors{ 108 "ConfigID": validation.Validate(v.ConfigID, validation.Required), 109 "Version": validation.Validate(v.Version, validation.Required), 110 "PolicyID": validation.Validate(v.PolicyID, validation.Required), 111 "Group": validation.Validate(v.Group, validation.Required), 112 "RulesetType": validation.Validate(v.RulesetType, validation.In(RulesetTypeActive, RulesetTypeEvaluation).Error( 113 fmt.Sprintf("value '%s' is invalid. Must be one of: 'active', 'evaluation' or '' (empty)", v.RulesetType))), 114 }.Filter() 115 } 116 117 // Validate validates a GetAttackGroupRecommendationsRequest. 118 func (v GetRuleRecommendationsRequest) Validate() error { 119 return validation.Errors{ 120 "ConfigID": validation.Validate(v.ConfigID, validation.Required), 121 "Version": validation.Validate(v.Version, validation.Required), 122 "PolicyID": validation.Validate(v.PolicyID, validation.Required), 123 "RuleID": validation.Validate(v.RuleID, validation.Required), 124 "RulesetType": validation.Validate(v.RulesetType, validation.In(RulesetTypeActive, RulesetTypeEvaluation).Error( 125 fmt.Sprintf("value '%s' is invalid. Must be one of: 'active', 'evaluation' or '' (empty)", v.RulesetType))), 126 }.Filter() 127 } 128 129 func (p *appsec) GetTuningRecommendations(ctx context.Context, params GetTuningRecommendationsRequest) (*GetTuningRecommendationsResponse, error) { 130 logger := p.Log(ctx) 131 logger.Debug("GetTuningRecommendations") 132 133 if err := params.Validate(); err != nil { 134 return nil, fmt.Errorf("%w: %s", ErrStructValidation, err.Error()) 135 } 136 137 uri := fmt.Sprintf( 138 "/appsec/v1/configs/%d/versions/%d/security-policies/%s/recommendations?standardException=true&type=%s", 139 params.ConfigID, 140 params.Version, 141 params.PolicyID, 142 params.RulesetType) 143 144 req, err := http.NewRequestWithContext(ctx, http.MethodGet, uri, nil) 145 if err != nil { 146 return nil, fmt.Errorf("failed to create GetTuningRecommendations request: %w", err) 147 } 148 req.Header.Set("Content-Type", "application/json") 149 150 var result GetTuningRecommendationsResponse 151 resp, err := p.Exec(req, &result) 152 if err != nil { 153 return nil, fmt.Errorf("get tuning recommendations request failed: %w", err) 154 } 155 if resp.StatusCode != http.StatusOK { 156 return nil, p.Error(resp) 157 } 158 159 return &result, nil 160 } 161 162 func (p *appsec) GetAttackGroupRecommendations(ctx context.Context, params GetAttackGroupRecommendationsRequest) (*GetAttackGroupRecommendationsResponse, error) { 163 logger := p.Log(ctx) 164 logger.Debug("GetAttackGroupRecommendations") 165 166 if err := params.Validate(); err != nil { 167 return nil, fmt.Errorf("%w: %s", ErrStructValidation, err.Error()) 168 } 169 170 uri := fmt.Sprintf( 171 "/appsec/v1/configs/%d/versions/%d/security-policies/%s/recommendations/attack-groups/%s?standardException=true&type=%s", 172 params.ConfigID, 173 params.Version, 174 params.PolicyID, 175 params.Group, 176 params.RulesetType, 177 ) 178 179 req, err := http.NewRequestWithContext(ctx, http.MethodGet, uri, nil) 180 if err != nil { 181 return nil, fmt.Errorf("failed to create GetAttackGroupRecommendations request: %w", err) 182 } 183 184 req.Header.Set("Content-Type", "application/json") 185 186 var result GetAttackGroupRecommendationsResponse 187 resp, err := p.Exec(req, &result) 188 if err != nil { 189 return nil, fmt.Errorf("get attack group recommendations request failed: %w", err) 190 } 191 if resp.StatusCode != http.StatusOK { 192 return nil, p.Error(resp) 193 } 194 195 return &result, nil 196 } 197 198 func (p *appsec) GetRuleRecommendations(ctx context.Context, params GetRuleRecommendationsRequest) (*GetRuleRecommendationsResponse, error) { 199 logger := p.Log(ctx) 200 logger.Debug("GetRuleRecommendations") 201 202 if err := params.Validate(); err != nil { 203 return nil, fmt.Errorf("%w: %s", ErrStructValidation, err.Error()) 204 } 205 206 uri := fmt.Sprintf( 207 "/appsec/v1/configs/%d/versions/%d/security-policies/%s/recommendations/rules/%d?standardException=true&type=%s", 208 params.ConfigID, 209 params.Version, 210 params.PolicyID, 211 params.RuleID, 212 params.RulesetType, 213 ) 214 215 req, err := http.NewRequestWithContext(ctx, http.MethodGet, uri, nil) 216 if err != nil { 217 return nil, fmt.Errorf("failed to create GetRuleRecommendations request: %w", err) 218 } 219 220 req.Header.Set("Content-Type", "application/json") 221 222 var result GetRuleRecommendationsResponse 223 resp, err := p.Exec(req, &result) 224 if err != nil { 225 return nil, fmt.Errorf("get rule recommendations request failed: %w", err) 226 } 227 if resp.StatusCode != http.StatusOK { 228 return nil, p.Error(resp) 229 } 230 231 return &result, nil 232 }