opensearch-project/opensearch-go

ISM Plugin `Conditions` struct is invalid

emtammaru opened this issue · 0 comments

The following Conditions struct is invalid and causes a 400 error to be returned by opensearch when a value is supplied:

Conditions []struct {
MinIndexAge string `json:"min_index_age,omitempty"`
MinRolloverAge string `json:"min_rollover_age,omitempty"`
MinDocCount int `json:"min_doc_count,omitempty"`
MinSize string `json:"min_size,omitempty"`
Cron *struct {
Expression string `json:"expression"`
Timezone string `json:"timezone"`
} `json:"cron,omitempty"`

Reason being, it should be a single object, not an array of objects -- see here for example: https://opensearch.org/docs/2.14/im-plugin/ism/api/#create-policy

            "conditions": {
              "min_index_age": "5m"
            }

Here's an example request to reproduce the error:

transitions := []ism.PolicyStateTransition{
		{
			StateName: "delete",
			Conditions: []struct {
				MinIndexAge    string `json:"min_index_age,omitempty"`
				MinRolloverAge string `json:"min_rollover_age,omitempty"`
				MinDocCount    int    `json:"min_doc_count,omitempty"`
				MinSize        string `json:"min_size,omitempty"`
				Cron           *struct {
					Expression string `json:"expression"`
					Timezone   string `json:"timezone"`
				} `json:"cron,omitempty"`
			}{
				{
					MinIndexAge: "1d",
				},
			},
		},
	}

	req := ism.PoliciesPutReq{
		Policy: policyName,
		Body: ism.PoliciesPutBody{
			Policy: ism.PolicyBody{
				Description: "retention policy of 1 day",
				DefaultState: "hot",
				States: []ism.PolicyState{
					{
						Name:        "hot",
						Transitions: &transitions,
					},
					{
						Name: "delete",
						Actions: []ism.PolicyStateAction{
							{
								Delete: &ism.PolicyStateDelete{},
							},
						},
					},
				},
			},
		},
	}

Causes the error:

status: 400, type: parsing_exception, reason: Failed to parse object: expecting token of type [START_OBJECT] but found [START_ARRAY], root_cause: [{parsing_exception Failed to parse object: expecting token of type [START_OBJECT] but found [START_ARRAY] }]

Simple fix here is to change from Conditions []struct { to Conditions struct {. But, the inline struct type declaration is not user friendly. Better solution is to create a type for Conditions such as:

// PolicyStateTransitionCondition is a sub type of PolicyStateTransition containing conditions for a transition
type PolicyStateTransitionCondition struct {
	MinIndexAge    string                              `json:"min_index_age,omitempty"`
	MinRolloverAge string                              `json:"min_rollover_age,omitempty"`
	MinDocCount    int                                 `json:"min_doc_count,omitempty"`
	MinSize        string                              `json:"min_size,omitempty"`
	Cron           *PolicyStateTransitionConditionCron `json:"cron,omitempty"`
}

type PolicyStateTransitionConditionCron struct {
	Expression string `json:"expression"`
	Timezone   string `json:"timezone"`
}

// PolicyStateTransition is a sub type of PolicyState containing information about transition to other states
type PolicyStateTransition struct {
	StateName  string                          `json:"state_name"`
	Conditions *PolicyStateTransitionCondition `json:"conditions"`
}