150 lines
4.6 KiB
Go
150 lines
4.6 KiB
Go
// Package index provides index-level operations for OpenSearch.
|
|
package index
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
)
|
|
|
|
var (
|
|
// ErrInvalidPolicy is returned when the policy configuration is invalid.
|
|
ErrInvalidPolicy = errors.New("invalid policy configuration")
|
|
)
|
|
|
|
// PolicyManager defines the interface for managing index lifecycle policies.
|
|
// This interface abstracts both AWS OpenSearch ISM (Index State Management)
|
|
// and Elasticsearch ILM (Index Lifecycle Management) to provide a unified API.
|
|
type PolicyManager interface {
|
|
// PutPolicy creates or updates a lifecycle policy.
|
|
PutPolicy(ctx context.Context, name string, policy *Policy) error
|
|
|
|
// GetPolicy retrieves a lifecycle policy by name.
|
|
GetPolicy(ctx context.Context, name string) (*Policy, error)
|
|
|
|
// DeletePolicy deletes a lifecycle policy by name.
|
|
DeletePolicy(ctx context.Context, name string) error
|
|
|
|
// ListPolicies retrieves all lifecycle policies.
|
|
ListPolicies(ctx context.Context) (map[string]*Policy, error)
|
|
}
|
|
|
|
// Policy represents a generic index lifecycle policy.
|
|
// It can be converted to ISM (AWS OpenSearch) or ILM (Elasticsearch) format.
|
|
type Policy struct {
|
|
// Description of the policy
|
|
Description string `json:"description,omitempty"`
|
|
|
|
// DefaultState is the initial state (ISM specific)
|
|
DefaultState string `json:"default_state,omitempty"`
|
|
|
|
// States defines the lifecycle states (ISM format)
|
|
States []State `json:"states,omitempty"`
|
|
|
|
// Phases defines the lifecycle phases (ILM format)
|
|
// This field is used when targeting Elasticsearch
|
|
Phases map[string]Phase `json:"phases,omitempty"`
|
|
|
|
// ISMTemplate for applying policy to indices (ISM specific)
|
|
ISMTemplate []ISMTemplate `json:"ism_template,omitempty"`
|
|
}
|
|
|
|
// State represents a state in ISM (AWS OpenSearch).
|
|
type State struct {
|
|
Name string `json:"name"`
|
|
Actions []Action `json:"actions,omitempty"`
|
|
Transitions []Transition `json:"transitions,omitempty"`
|
|
}
|
|
|
|
// Action represents an action within a state.
|
|
// In ISM, actions are serialized as a single key-value object where
|
|
// the key is the action type and the value is the configuration.
|
|
type Action struct {
|
|
// Config contains the action type as the key and its configuration as the value
|
|
// Example: {"rollover": {"min_index_age": "1d"}}
|
|
Config map[string]interface{}
|
|
}
|
|
|
|
// NewAction creates a new action with the specified type and configuration.
|
|
func NewAction(actionType string, config map[string]interface{}) Action {
|
|
return Action{
|
|
Config: map[string]interface{}{
|
|
actionType: config,
|
|
},
|
|
}
|
|
}
|
|
|
|
// MarshalJSON implements custom JSON marshaling for Action.
|
|
// It directly marshals the Config map instead of wrapping it in a "Config" field.
|
|
func (a Action) MarshalJSON() ([]byte, error) {
|
|
return json.Marshal(a.Config)
|
|
}
|
|
|
|
// UnmarshalJSON implements custom JSON unmarshaling for Action.
|
|
func (a *Action) UnmarshalJSON(data []byte) error {
|
|
return json.Unmarshal(data, &a.Config)
|
|
}
|
|
|
|
// Transition defines when to move to the next state.
|
|
type Transition struct {
|
|
StateName string `json:"state_name"`
|
|
Conditions *Conditions `json:"conditions,omitempty"`
|
|
}
|
|
|
|
// Conditions defines the conditions for state transitions.
|
|
type Conditions struct {
|
|
MinIndexAge string `json:"min_index_age,omitempty"`
|
|
MinDocCount *int64 `json:"min_doc_count,omitempty"`
|
|
MinSize string `json:"min_size,omitempty"`
|
|
}
|
|
|
|
// Phase represents a phase in ILM (Elasticsearch).
|
|
// This is for future Elasticsearch compatibility.
|
|
type Phase struct {
|
|
MinAge string `json:"min_age,omitempty"`
|
|
Actions map[string]interface{} `json:"actions,omitempty"`
|
|
}
|
|
|
|
// ISMTemplate defines index patterns for automatic policy application.
|
|
type ISMTemplate struct {
|
|
IndexPatterns []string `json:"index_patterns"`
|
|
Priority int `json:"priority"`
|
|
}
|
|
|
|
// Validate checks if the policy configuration is valid.
|
|
func (p *Policy) Validate() error {
|
|
if p == nil {
|
|
return ErrInvalidPolicy
|
|
}
|
|
|
|
// For ISM: must have at least one state with a default_state
|
|
if len(p.States) > 0 {
|
|
if p.DefaultState == "" {
|
|
return errors.New("default_state is required when states are defined")
|
|
}
|
|
|
|
// Verify default_state exists in states
|
|
found := false
|
|
for _, state := range p.States {
|
|
if state.Name == p.DefaultState {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
if !found {
|
|
return errors.New("default_state must match one of the defined states")
|
|
}
|
|
}
|
|
|
|
// For ILM: must have at least one phase
|
|
if len(p.Phases) > 0 && len(p.States) > 0 {
|
|
return errors.New("cannot define both ISM states and ILM phases in the same policy")
|
|
}
|
|
|
|
if len(p.States) == 0 && len(p.Phases) == 0 {
|
|
return errors.New("policy must define either states (ISM) or phases (ILM)")
|
|
}
|
|
|
|
return nil
|
|
}
|