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