1// Copyright 2012-present Oliver Eilhard. All rights reserved.
2// Use of this source code is governed by a MIT-license.
3// See http://olivere.mit-license.org/license.txt for details.
4
5package elastic
6
7import (
8	"context"
9	"encoding/json"
10	"fmt"
11	"net/url"
12	"strings"
13	"time"
14
15	"github.com/olivere/elastic/uritemplates"
16)
17
18// SnapshotGetService lists the snapshots on a repository
19// See https://www.elastic.co/guide/en/elasticsearch/reference/6.7/modules-snapshots.html
20// for details.
21type SnapshotGetService struct {
22	client            *Client
23	repository        string
24	snapshot          []string
25	masterTimeout     string
26	ignoreUnavailable *bool
27	verbose           *bool
28}
29
30// NewSnapshotGetService creates a new SnapshotGetService.
31func NewSnapshotGetService(client *Client) *SnapshotGetService {
32	return &SnapshotGetService{
33		client: client,
34	}
35}
36
37// Repository is the repository name.
38func (s *SnapshotGetService) Repository(repository string) *SnapshotGetService {
39	s.repository = repository
40	return s
41}
42
43// Snapshot is the list of snapshot names. If not set, defaults to all snapshots.
44func (s *SnapshotGetService) Snapshot(snapshots ...string) *SnapshotGetService {
45	s.snapshot = append(s.snapshot, snapshots...)
46	return s
47}
48
49// MasterTimeout specifies an explicit operation timeout for connection to master node.
50func (s *SnapshotGetService) MasterTimeout(masterTimeout string) *SnapshotGetService {
51	s.masterTimeout = masterTimeout
52	return s
53}
54
55// IgnoreUnavailable specifies whether to ignore unavailable snapshots, defaults to false
56func (s *SnapshotGetService) IgnoreUnavailable(ignoreUnavailable bool) *SnapshotGetService {
57	s.ignoreUnavailable = &ignoreUnavailable
58	return s
59}
60
61// Verbose specifies whether to show verbose snapshot info or only show the basic info found in the repository index blob
62func (s *SnapshotGetService) Verbose(verbose bool) *SnapshotGetService {
63	s.verbose = &verbose
64	return s
65}
66
67// buildURL builds the URL for the operation.
68func (s *SnapshotGetService) buildURL() (string, url.Values, error) {
69	// Build URL
70	var err error
71	var path string
72	if len(s.snapshot) > 0 {
73		path, err = uritemplates.Expand("/_snapshot/{repository}/{snapshot}", map[string]string{
74			"repository": s.repository,
75			"snapshot":   strings.Join(s.snapshot, ","),
76		})
77	} else {
78		path, err = uritemplates.Expand("/_snapshot/{repository}/_all", map[string]string{
79			"repository": s.repository,
80		})
81	}
82	if err != nil {
83		return "", url.Values{}, err
84	}
85
86	// Add query string parameters
87	params := url.Values{}
88	if s.masterTimeout != "" {
89		params.Set("master_timeout", s.masterTimeout)
90	}
91	if s.ignoreUnavailable != nil {
92		params.Set("ignore_unavailable", fmt.Sprint(*s.ignoreUnavailable))
93	}
94	if s.verbose != nil {
95		params.Set("verbose", fmt.Sprint(*s.verbose))
96	}
97	return path, params, nil
98}
99
100// Validate checks if the operation is valid.
101func (s *SnapshotGetService) Validate() error {
102	var invalid []string
103	if s.repository == "" {
104		invalid = append(invalid, "Repository")
105	}
106	if len(invalid) > 0 {
107		return fmt.Errorf("missing required fields: %v", invalid)
108	}
109	return nil
110}
111
112// Do executes the operation.
113func (s *SnapshotGetService) Do(ctx context.Context) (*SnapshotGetResponse, error) {
114	// Check pre-conditions
115	if err := s.Validate(); err != nil {
116		return nil, err
117	}
118
119	// Get URL for request
120	path, params, err := s.buildURL()
121	if err != nil {
122		return nil, err
123	}
124
125	// Get HTTP response
126	res, err := s.client.PerformRequest(ctx, PerformRequestOptions{
127		Method: "GET",
128		Path:   path,
129		Params: params,
130	})
131	if err != nil {
132		return nil, err
133	}
134
135	// Return operation response
136	ret := new(SnapshotGetResponse)
137	if err := json.Unmarshal(res.Body, ret); err != nil {
138		return nil, err
139	}
140	return ret, nil
141}
142
143// SnapshotGetResponse is the response of SnapshotGetService.Do.
144type SnapshotGetResponse struct {
145	Snapshots []*Snapshot `json:"snapshots"`
146}
147
148// Snapshot contains all information about a single snapshot
149type Snapshot struct {
150	Snapshot          string                 `json:"snapshot"`
151	UUID              string                 `json:"uuid"`
152	VersionID         int                    `json:"version_id"`
153	Version           string                 `json:"version"`
154	Indices           []string               `json:"indices"`
155	State             string                 `json:"state"`
156	Reason            string                 `json:"reason"`
157	StartTime         time.Time              `json:"start_time"`
158	StartTimeInMillis int64                  `json:"start_time_in_millis"`
159	EndTime           time.Time              `json:"end_time"`
160	EndTimeInMillis   int64                  `json:"end_time_in_millis"`
161	DurationInMillis  int64                  `json:"duration_in_millis"`
162	Failures          []SnapshotShardFailure `json:"failures"`
163	Shards            *ShardsInfo            `json:"shards"`
164}
165