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  }