diff --git a/client.go b/client.go index a725f7c13..ce213bcb0 100644 --- a/client.go +++ b/client.go @@ -1631,14 +1631,30 @@ func (c *Client) TasksList() *TasksListService { // -- Snapshot and Restore -- // TODO Snapshot Create -// TODO Snapshot Create Repository // TODO Snapshot Delete -// TODO Snapshot Delete Repository // TODO Snapshot Get -// TODO Snapshot Get Repository // TODO Snapshot Restore // TODO Snapshot Status -// TODO Snapshot Verify Repository + +// SnapshotCreateRepository creates or updates a snapshot repository. +func (c *Client) SnapshotCreateRepository(repository string) *SnapshotCreateRepositoryService { + return NewSnapshotCreateRepositoryService(c).Repository(repository) +} + +// SnapshotDeleteRepository deletes a snapshot repository. +func (c *Client) SnapshotDeleteRepository(repositories ...string) *SnapshotDeleteRepositoryService { + return NewSnapshotDeleteRepositoryService(c).Repository(repositories...) +} + +// SnapshotGetRepository gets a snapshot repository. +func (c *Client) SnapshotGetRepository(repositories ...string) *SnapshotGetRepositoryService { + return NewSnapshotGetRepositoryService(c).Repository(repositories...) +} + +// SnapshotVerifyRepository verifies a snapshot repository. +func (c *Client) SnapshotVerifyRepository(repository string) *SnapshotVerifyRepositoryService { + return NewSnapshotVerifyRepositoryService(c).Repository(repository) +} // -- Helpers and shortcuts -- diff --git a/snapshot_create_repository.go b/snapshot_create_repository.go new file mode 100644 index 000000000..6701bbbb3 --- /dev/null +++ b/snapshot_create_repository.go @@ -0,0 +1,157 @@ +// Copyright 2012-2017 Oliver Eilhard. All rights reserved. +// Use of this source code is governed by a MIT-license. +// See http://olivere.mit-license.org/license.txt for details. + +package elastic + +import ( + "context" + "encoding/json" + "fmt" + "net/url" + + "gopkg.in/olivere/elastic.v5/uritemplates" +) + +// SnapshotCreateRepositoryService is documented at https://www.elastic.co/guide/en/elasticsearch/reference/5.x/modules-snapshots.html. +type SnapshotCreateRepositoryService struct { + client *Client + pretty bool + repository string + masterTimeout string + timeout string + verify *bool + bodyJson interface{} + bodyString string +} + +// NewSnapshotCreateRepositoryService creates a new SnapshotCreateRepositoryService. +func NewSnapshotCreateRepositoryService(client *Client) *SnapshotCreateRepositoryService { + return &SnapshotCreateRepositoryService{ + client: client, + } +} + +// Repository is documented as: A repository name. +func (s *SnapshotCreateRepositoryService) Repository(repository string) *SnapshotCreateRepositoryService { + s.repository = repository + return s +} + +// MasterTimeout is documented as: Explicit operation timeout for connection to master node. +func (s *SnapshotCreateRepositoryService) MasterTimeout(masterTimeout string) *SnapshotCreateRepositoryService { + s.masterTimeout = masterTimeout + return s +} + +// Timeout is documented as: Explicit operation timeout. +func (s *SnapshotCreateRepositoryService) Timeout(timeout string) *SnapshotCreateRepositoryService { + s.timeout = timeout + return s +} + +// Verify is documented as: Whether to verify the repository after creation. +func (s *SnapshotCreateRepositoryService) Verify(verify bool) *SnapshotCreateRepositoryService { + s.verify = &verify + return s +} + +// Pretty indicates that the JSON response be indented and human readable. +func (s *SnapshotCreateRepositoryService) Pretty(pretty bool) *SnapshotCreateRepositoryService { + s.pretty = pretty + return s +} + +// BodyJson is documented as: The repository definition. +func (s *SnapshotCreateRepositoryService) BodyJson(body interface{}) *SnapshotCreateRepositoryService { + s.bodyJson = body + return s +} + +// BodyString is documented as: The repository definition. +func (s *SnapshotCreateRepositoryService) BodyString(body string) *SnapshotCreateRepositoryService { + s.bodyString = body + return s +} + +// buildURL builds the URL for the operation. +func (s *SnapshotCreateRepositoryService) buildURL() (string, url.Values, error) { + // Build URL + path, err := uritemplates.Expand("/_snapshot/{repository}", map[string]string{ + "repository": s.repository, + }) + if err != nil { + return "", url.Values{}, err + } + + // Add query string parameters + params := url.Values{} + if s.pretty { + params.Set("pretty", "1") + } + if s.masterTimeout != "" { + params.Set("master_timeout", s.masterTimeout) + } + if s.timeout != "" { + params.Set("timeout", s.timeout) + } + if s.verify != nil { + params.Set("verify", fmt.Sprintf("%v", *s.verify)) + } + return path, params, nil +} + +// Validate checks if the operation is valid. +func (s *SnapshotCreateRepositoryService) Validate() error { + var invalid []string + if s.repository == "" { + invalid = append(invalid, "Repository") + } + if s.bodyString == "" && s.bodyJson == nil { + invalid = append(invalid, "BodyJson") + } + if len(invalid) > 0 { + return fmt.Errorf("missing required fields: %v", invalid) + } + return nil +} + +// Do executes the operation. +func (s *SnapshotCreateRepositoryService) Do(ctx context.Context) (*SnapshotCreateRepositoryResponse, error) { + // Check pre-conditions + if err := s.Validate(); err != nil { + return nil, err + } + + // Get URL for request + path, params, err := s.buildURL() + if err != nil { + return nil, err + } + + // Setup HTTP request body + var body interface{} + if s.bodyJson != nil { + body = s.bodyJson + } else { + body = s.bodyString + } + + // Get HTTP response + res, err := s.client.PerformRequest(ctx, "PUT", path, params, body) + if err != nil { + return nil, err + } + + // Return operation response + ret := new(SnapshotCreateRepositoryResponse) + if err := json.Unmarshal(res.Body, ret); err != nil { + return nil, err + } + return ret, nil +} + +// SnapshotCreateRepositoryResponse is the response of SnapshotCreateRepositoryService.Do. +type SnapshotCreateRepositoryResponse struct { + Acknowledged bool `json:"acknowledged"` +} diff --git a/snapshot_create_repository_test.go b/snapshot_create_repository_test.go new file mode 100644 index 000000000..6b835c489 --- /dev/null +++ b/snapshot_create_repository_test.go @@ -0,0 +1,27 @@ +package elastic + +import "testing" + +func TestSnapshotPutRepositoryURL(t *testing.T) { + client := setupTestClient(t) + + tests := []struct { + Repository string + Expected string + }{ + { + "repo", + "/_snapshot/repo", + }, + } + + for _, test := range tests { + path, _, err := client.SnapshotCreateRepository(test.Repository).buildURL() + if err != nil { + t.Fatal(err) + } + if path != test.Expected { + t.Errorf("expected %q; got: %q", test.Expected, path) + } + } +} diff --git a/snapshot_delete_repository.go b/snapshot_delete_repository.go new file mode 100644 index 000000000..dc05cfa8b --- /dev/null +++ b/snapshot_delete_repository.go @@ -0,0 +1,124 @@ +// Copyright 2012-2017 Oliver Eilhard. All rights reserved. +// Use of this source code is governed by a MIT-license. +// See http://olivere.mit-license.org/license.txt for details. + +package elastic + +import ( + "context" + "encoding/json" + "fmt" + "net/url" + "strings" + + "gopkg.in/olivere/elastic.v5/uritemplates" +) + +// SnapshotDeleteRepositoryService is documented at https://www.elastic.co/guide/en/elasticsearch/reference/5.x/modules-snapshots.html. +type SnapshotDeleteRepositoryService struct { + client *Client + pretty bool + repository []string + masterTimeout string + timeout string +} + +// NewSnapshotDeleteRepositoryService creates a new SnapshotDeleteRepositoryService. +func NewSnapshotDeleteRepositoryService(client *Client) *SnapshotDeleteRepositoryService { + return &SnapshotDeleteRepositoryService{ + client: client, + repository: make([]string, 0), + } +} + +// Repository is documented as: A comma-separated list of repository names. +func (s *SnapshotDeleteRepositoryService) Repository(repositories ...string) *SnapshotDeleteRepositoryService { + s.repository = append(s.repository, repositories...) + return s +} + +// MasterTimeout is documented as: Explicit operation timeout for connection to master node. +func (s *SnapshotDeleteRepositoryService) MasterTimeout(masterTimeout string) *SnapshotDeleteRepositoryService { + s.masterTimeout = masterTimeout + return s +} + +// Timeout is documented as: Explicit operation timeout. +func (s *SnapshotDeleteRepositoryService) Timeout(timeout string) *SnapshotDeleteRepositoryService { + s.timeout = timeout + return s +} + +// Pretty indicates that the JSON response be indented and human readable. +func (s *SnapshotDeleteRepositoryService) Pretty(pretty bool) *SnapshotDeleteRepositoryService { + s.pretty = pretty + return s +} + +// buildURL builds the URL for the operation. +func (s *SnapshotDeleteRepositoryService) buildURL() (string, url.Values, error) { + // Build URL + path, err := uritemplates.Expand("/_snapshot/{repository}", map[string]string{ + "repository": strings.Join(s.repository, ","), + }) + if err != nil { + return "", url.Values{}, err + } + + // Add query string parameters + params := url.Values{} + if s.pretty { + params.Set("pretty", "1") + } + if s.masterTimeout != "" { + params.Set("master_timeout", s.masterTimeout) + } + if s.timeout != "" { + params.Set("timeout", s.timeout) + } + return path, params, nil +} + +// Validate checks if the operation is valid. +func (s *SnapshotDeleteRepositoryService) Validate() error { + var invalid []string + if len(s.repository) == 0 { + invalid = append(invalid, "Repository") + } + if len(invalid) > 0 { + return fmt.Errorf("missing required fields: %v", invalid) + } + return nil +} + +// Do executes the operation. +func (s *SnapshotDeleteRepositoryService) Do(ctx context.Context) (*SnapshotDeleteRepositoryResponse, error) { + // Check pre-conditions + if err := s.Validate(); err != nil { + return nil, err + } + + // Get URL for request + path, params, err := s.buildURL() + if err != nil { + return nil, err + } + + // Get HTTP response + res, err := s.client.PerformRequest(ctx, "DELETE", path, params, nil) + if err != nil { + return nil, err + } + + // Return operation response + ret := new(SnapshotDeleteRepositoryResponse) + if err := json.Unmarshal(res.Body, ret); err != nil { + return nil, err + } + return ret, nil +} + +// SnapshotDeleteRepositoryResponse is the response of SnapshotDeleteRepositoryService.Do. +type SnapshotDeleteRepositoryResponse struct { + Acknowledged bool `json:"acknowledged"` +} diff --git a/snapshot_delete_repository_test.go b/snapshot_delete_repository_test.go new file mode 100644 index 000000000..d2c673e5e --- /dev/null +++ b/snapshot_delete_repository_test.go @@ -0,0 +1,31 @@ +package elastic + +import "testing" + +func TestSnapshotDeleteRepositoryURL(t *testing.T) { + client := setupTestClient(t) + + tests := []struct { + Repository []string + Expected string + }{ + { + []string{"repo1"}, + "/_snapshot/repo1", + }, + { + []string{"repo1", "repo2"}, + "/_snapshot/repo1%2Crepo2", + }, + } + + for _, test := range tests { + path, _, err := client.SnapshotDeleteRepository(test.Repository...).buildURL() + if err != nil { + t.Fatal(err) + } + if path != test.Expected { + t.Errorf("expected %q; got: %q", test.Expected, path) + } + } +} diff --git a/snapshot_get_repository.go b/snapshot_get_repository.go new file mode 100644 index 000000000..948deb138 --- /dev/null +++ b/snapshot_get_repository.go @@ -0,0 +1,126 @@ +// Copyright 2012-2017 Oliver Eilhard. All rights reserved. +// Use of this source code is governed by a MIT-license. +// See http://olivere.mit-license.org/license.txt for details. + +package elastic + +import ( + "context" + "encoding/json" + "fmt" + "net/url" + "strings" + + "gopkg.in/olivere/elastic.v5/uritemplates" +) + +// SnapshotGetRepositoryService is documented at https://www.elastic.co/guide/en/elasticsearch/reference/5.x/modules-snapshots.html. +type SnapshotGetRepositoryService struct { + client *Client + pretty bool + repository []string + local *bool + masterTimeout string +} + +// NewSnapshotGetRepositoryService creates a new SnapshotGetRepositoryService. +func NewSnapshotGetRepositoryService(client *Client) *SnapshotGetRepositoryService { + return &SnapshotGetRepositoryService{ + client: client, + repository: make([]string, 0), + } +} + +// Repository is documented as: A comma-separated list of repository names. +func (s *SnapshotGetRepositoryService) Repository(repositories ...string) *SnapshotGetRepositoryService { + s.repository = append(s.repository, repositories...) + return s +} + +// Local is documented as: Return local information, do not retrieve the state from master node (default: false). +func (s *SnapshotGetRepositoryService) Local(local bool) *SnapshotGetRepositoryService { + s.local = &local + return s +} + +// MasterTimeout is documented as: Explicit operation timeout for connection to master node. +func (s *SnapshotGetRepositoryService) MasterTimeout(masterTimeout string) *SnapshotGetRepositoryService { + s.masterTimeout = masterTimeout + return s +} + +// Pretty indicates that the JSON response be indented and human readable. +func (s *SnapshotGetRepositoryService) Pretty(pretty bool) *SnapshotGetRepositoryService { + s.pretty = pretty + return s +} + +// buildURL builds the URL for the operation. +func (s *SnapshotGetRepositoryService) buildURL() (string, url.Values, error) { + // Build URL + var err error + var path string + if len(s.repository) > 0 { + path, err = uritemplates.Expand("/_snapshot/{repository}", map[string]string{ + "repository": strings.Join(s.repository, ","), + }) + } else { + path = "/_snapshot" + } + if err != nil { + return "", url.Values{}, err + } + + // Add query string parameters + params := url.Values{} + if s.pretty { + params.Set("pretty", "1") + } + if s.local != nil { + params.Set("local", fmt.Sprintf("%v", *s.local)) + } + if s.masterTimeout != "" { + params.Set("master_timeout", s.masterTimeout) + } + return path, params, nil +} + +// Validate checks if the operation is valid. +func (s *SnapshotGetRepositoryService) Validate() error { + return nil +} + +// Do executes the operation. +func (s *SnapshotGetRepositoryService) Do(ctx context.Context) (SnapshotGetRepositoryResponse, error) { + // Check pre-conditions + if err := s.Validate(); err != nil { + return nil, err + } + + // Get URL for request + path, params, err := s.buildURL() + if err != nil { + return nil, err + } + + // Get HTTP response + res, err := s.client.PerformRequest(ctx, "GET", path, params, nil) + if err != nil { + return nil, err + } + + // Return operation response + var ret SnapshotGetRepositoryResponse + if err := json.Unmarshal(res.Body, &ret); err != nil { + return nil, err + } + return ret, nil +} + +// SnapshotGetRepositoryResponse is the response of SnapshotGetRepositoryService.Do. +type SnapshotGetRepositoryResponse map[string]*SnapshotRepository + +type SnapshotRepository struct { + Type string `json:"type"` + Settings interface{} `json:"settings,omitempty"` +} diff --git a/snapshot_get_repository_test.go b/snapshot_get_repository_test.go new file mode 100644 index 000000000..607cc930b --- /dev/null +++ b/snapshot_get_repository_test.go @@ -0,0 +1,35 @@ +package elastic + +import "testing" + +func TestSnapshotGetRepositoryURL(t *testing.T) { + client := setupTestClient(t) + + tests := []struct { + Repository []string + Expected string + }{ + { + []string{}, + "/_snapshot", + }, + { + []string{"repo1"}, + "/_snapshot/repo1", + }, + { + []string{"repo1", "repo2"}, + "/_snapshot/repo1%2Crepo2", + }, + } + + for _, test := range tests { + path, _, err := client.SnapshotGetRepository(test.Repository...).buildURL() + if err != nil { + t.Fatal(err) + } + if path != test.Expected { + t.Errorf("expected %q; got: %q", test.Expected, path) + } + } +} diff --git a/snapshot_verify_repository.go b/snapshot_verify_repository.go new file mode 100644 index 000000000..acedd3da2 --- /dev/null +++ b/snapshot_verify_repository.go @@ -0,0 +1,126 @@ +// Copyright 2012-2017 Oliver Eilhard. All rights reserved. +// Use of this source code is governed by a MIT-license. +// See http://olivere.mit-license.org/license.txt for details. + +package elastic + +import ( + "context" + "encoding/json" + "fmt" + "net/url" + + "gopkg.in/olivere/elastic.v5/uritemplates" +) + +// SnapshotVerifyRepositoryService is documented at https://www.elastic.co/guide/en/elasticsearch/reference/5.x/modules-snapshots.html. +type SnapshotVerifyRepositoryService struct { + client *Client + pretty bool + repository string + masterTimeout string + timeout string +} + +// NewSnapshotVerifyRepositoryService creates a new SnapshotVerifyRepositoryService. +func NewSnapshotVerifyRepositoryService(client *Client) *SnapshotVerifyRepositoryService { + return &SnapshotVerifyRepositoryService{ + client: client, + } +} + +// Repository is documented as: A repository name. +func (s *SnapshotVerifyRepositoryService) Repository(repository string) *SnapshotVerifyRepositoryService { + s.repository = repository + return s +} + +// MasterTimeout is documented as: Explicit operation timeout for connection to master node. +func (s *SnapshotVerifyRepositoryService) MasterTimeout(masterTimeout string) *SnapshotVerifyRepositoryService { + s.masterTimeout = masterTimeout + return s +} + +// Timeout is documented as: Explicit operation timeout. +func (s *SnapshotVerifyRepositoryService) Timeout(timeout string) *SnapshotVerifyRepositoryService { + s.timeout = timeout + return s +} + +// Pretty indicates that the JSON response be indented and human readable. +func (s *SnapshotVerifyRepositoryService) Pretty(pretty bool) *SnapshotVerifyRepositoryService { + s.pretty = pretty + return s +} + +// buildURL builds the URL for the operation. +func (s *SnapshotVerifyRepositoryService) buildURL() (string, url.Values, error) { + // Build URL + path, err := uritemplates.Expand("/_snapshot/{repository}/_verify", map[string]string{ + "repository": s.repository, + }) + if err != nil { + return "", url.Values{}, err + } + + // Add query string parameters + params := url.Values{} + if s.pretty { + params.Set("pretty", "1") + } + if s.masterTimeout != "" { + params.Set("master_timeout", s.masterTimeout) + } + if s.timeout != "" { + params.Set("timeout", s.timeout) + } + return path, params, nil +} + +// Validate checks if the operation is valid. +func (s *SnapshotVerifyRepositoryService) Validate() error { + var invalid []string + if s.repository == "" { + invalid = append(invalid, "Repository") + } + if len(invalid) > 0 { + return fmt.Errorf("missing required fields: %v", invalid) + } + return nil +} + +// Do executes the operation. +func (s *SnapshotVerifyRepositoryService) Do(ctx context.Context) (*SnapshotVerifyRepositoryResponse, error) { + // Check pre-conditions + if err := s.Validate(); err != nil { + return nil, err + } + + // Get URL for request + path, params, err := s.buildURL() + if err != nil { + return nil, err + } + + // Get HTTP response + res, err := s.client.PerformRequest(ctx, "POST", path, params, nil) + if err != nil { + return nil, err + } + + // Return operation response + ret := new(SnapshotVerifyRepositoryResponse) + if err := json.Unmarshal(res.Body, ret); err != nil { + return nil, err + } + return ret, nil +} + +// SnapshotVerifyRepositoryResponse is the response of SnapshotVerifyRepositoryService.Do. +type SnapshotVerifyRepositoryResponse struct { + Nodes map[string]*SnapshotVerifyRepositoryNode `json:"nodes"` +} + +type SnapshotVerifyRepositoryNode struct { + Name string `json:"name"` +} diff --git a/snapshot_verify_repository_test.go b/snapshot_verify_repository_test.go new file mode 100644 index 000000000..99839979d --- /dev/null +++ b/snapshot_verify_repository_test.go @@ -0,0 +1,27 @@ +package elastic + +import "testing" + +func TestSnapshotVerifyRepositoryURL(t *testing.T) { + client := setupTestClient(t) + + tests := []struct { + Repository string + Expected string + }{ + { + "repo", + "/_snapshot/repo/_verify", + }, + } + + for _, test := range tests { + path, _, err := client.SnapshotVerifyRepository(test.Repository).buildURL() + if err != nil { + t.Fatal(err) + } + if path != test.Expected { + t.Errorf("expected %q; got: %q", test.Expected, path) + } + } +}