internal/elasticsearch/ingest/packages.go (92 lines of code) (raw):

// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one // or more contributor license agreements. Licensed under the Elastic License; // you may not use this file except in compliance with the Elastic License. package ingest import ( "context" "encoding/json" "fmt" "io" "net/http" "slices" "github.com/elastic/elastic-package/internal/elasticsearch" ) // IndexTemplate contains information related to an index template for exporting purpouses. // It contains a partially parsed index template and the original JSON from the response. type IndexTemplate struct { TemplateName string `json:"name"` IndexTemplate struct { Meta struct { ManagedBy string `json:"managed_by"` Managed bool `json:"managed"` Package struct { Name string `json:"name"` } `json:"package"` } `json:"_meta"` ComposedOf []string `json:"composed_of"` Template struct { Settings TemplateSettings `json:"settings"` } `json:"template"` } `json:"index_template"` raw json.RawMessage } // TemplateSettings are common settings to all kinds of templates. type TemplateSettings struct { Index struct { DefaultPipeline string `json:"default_pipeline"` FinalPipeline string `json:"final_pipeline"` Lifecycle struct { Name string `json:"name"` } `json:"lifecycle"` } `json:"index"` } // Name returns the name of the index template. func (t IndexTemplate) Name() string { return t.TemplateName } // JSON returns the JSON representation of the index template. func (t IndexTemplate) JSON() []byte { return []byte(t.raw) } // TemplateSettings returns the template settings of this template. func (t IndexTemplate) TemplateSettings() TemplateSettings { return t.IndexTemplate.Template.Settings } type getIndexTemplateResponse struct { IndexTemplates []json.RawMessage `json:"index_templates"` } // GetIndexTemplatesForPackage gets the index templates installed for a package. func GetIndexTemplatesForPackage(ctx context.Context, api *elasticsearch.API, packageName string) ([]IndexTemplate, error) { resp, err := api.Indices.GetIndexTemplate( api.Indices.GetIndexTemplate.WithContext(ctx), // Wildcard may be too wide, we will double check below if it is a managed template. api.Indices.GetIndexTemplate.WithName(fmt.Sprintf("*-%s.*", packageName)), ) if err != nil { return nil, fmt.Errorf("failed to get index templates: %w", err) } defer resp.Body.Close() if resp.StatusCode == http.StatusNotFound { // Some packages don't have index templates. return nil, nil } if resp.IsError() { return nil, fmt.Errorf("failed to get index templates: %s", resp.String()) } d, err := io.ReadAll(resp.Body) if err != nil { return nil, fmt.Errorf("failed to read response body: %w", err) } var templateResponse getIndexTemplateResponse err = json.Unmarshal(d, &templateResponse) if err != nil { return nil, fmt.Errorf("failed to decode response: %w", err) } var indexTemplates []IndexTemplate for _, indexTemplateRaw := range templateResponse.IndexTemplates { var indexTemplate IndexTemplate err = json.Unmarshal(indexTemplateRaw, &indexTemplate) if err != nil { return nil, fmt.Errorf("failed to parse index template: %w", err) } indexTemplate.raw = indexTemplateRaw meta := indexTemplate.IndexTemplate.Meta if meta.Package.Name != packageName || !managedByFleet(meta.ManagedBy) { // This is not the droid you are looking for. continue } indexTemplates = append(indexTemplates, indexTemplate) } return indexTemplates, nil } func managedByFleet(managedBy string) bool { var managers = []string{"ingest-manager", "fleet"} return slices.Contains(managers, managedBy) }