Skip to content

Commit

Permalink
Add resource ec_snapshot_repository
Browse files Browse the repository at this point in the history
This updates elastic/cloud-sdk-go to v1.12.1 because of
`snaprepoapi.S3Config.PathStyleAccess` which was added there.
  • Loading branch information
pascal-hofmann committed Mar 31, 2023
1 parent 784192a commit f33684d
Show file tree
Hide file tree
Showing 10 changed files with 1,124 additions and 5 deletions.
61 changes: 61 additions & 0 deletions docs/resources/ec_snapshot_repository.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
---
page_title: "ec_snapshot_repository Resource - terraform-provider-ec"
description: |-
Manages Elastic Cloud Enterprise snapshot repositories.
---

# ec_snapshot_repository (Resource)

Manages Elastic Cloud Enterprise snapshot repositories.

~> **This resource can only be used with Elastic Cloud Enterprise** For Elastic Cloud SaaS please use the [elasticstack_elasticsearch_snapshot_repository](https://registry.terraform.io/providers/elastic/elasticstack/latest/docs/resources/elasticsearch_snapshot_repository) resource from the [Elastic Stack terraform provider](https://registry.terraform.io/providers/elastic/elasticstack/latest).

## Example Usage

```hcl
resource "ec_snapshot_repository" "this" {
name = "my-snapshot-repository"
s3 = {
bucket = "my-bucket"
access_key = "my-access-key"
secret_key = "my-secret-key"
}
}
```


## Schema

### Required

- `name` (String) The name of the snapshot repository configuration.
- `s3` (Attributes) S3 repository settings. (see [below for nested schema](#nestedatt--s3))

### Read-Only

- `id` (String) Unique identifier of this resource.

<a id="nestedatt--s3"></a>
### Nested Schema for `s3`

Required:

- `bucket` (String) (Required) Name of the S3 bucket to use for snapshots.

Optional:

- `access_key` (String) An S3 access key. If set, the secret_key setting must also be specified. If unset, the client will use the instance or container role instead.
- `secret_key` (String, Sensitive) An S3 secret key. If set, the access_key setting must also be specified.
- `server_side_encryption` (Boolean) When set to true files are encrypted on server side using AES256 algorithm. Defaults to false.
- `endpoint` (String) The S3 service endpoint to connect to. This defaults to s3.amazonaws.com but the AWS documentation lists alternative S3 endpoints. If you are using an S3-compatible service then you should set this to the service’s endpoint.
- `path_style_access` (Boolean) Whether to force the use of the path style access pattern. If true, the path style access pattern will be used. If false, the access pattern will be automatically determined by the AWS Java SDK (See AWS documentation for details). Defaults to false.
- `region` (String) Allows specifying the signing region to use. Specifying this setting manually should not be necessary for most use cases. Generally, the SDK will correctly guess the signing region to use. It should be considered an expert level setting to support S3-compatible APIs that require v4 signatures and use a region other than the default us-east-1. Defaults to empty string which means that the SDK will try to automatically determine the correct signing region.


## Import

You can import snapshot repositories using the `name`, for example:

```
$ terraform import ec_snapshot_repository.this my-snapshot-repository
```
81 changes: 81 additions & 0 deletions ec/ecresource/snapshotrepositoryresource/create.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// Licensed to Elasticsearch B.V. under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Elasticsearch B.V. licenses this file to you under
// the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

package snapshotrepositoryresource

import (
"context"

"github.com/hashicorp/terraform-plugin-framework/resource"

"github.com/elastic/cloud-sdk-go/pkg/api/platformapi/snaprepoapi"
)

func (r *Resource) Create(ctx context.Context, request resource.CreateRequest, response *resource.CreateResponse) {
if !resourceReady(r, &response.Diagnostics) {
return
}

var newState modelV0

diags := request.Plan.Get(ctx, &newState)
response.Diagnostics.Append(diags...)
if response.Diagnostics.HasError() {
return
}

err := snaprepoapi.Set(
snaprepoapi.SetParams{
API: r.client,
Region: "ece-region", // This resource is only usable for ECE installations. Thus, we can default to ece-region.
Name: newState.Name.Value,
Type: "s3",
Config: snaprepoapi.S3Config{
Region: newState.S3.Region.Value,
Bucket: newState.S3.Bucket.Value,
AccessKey: newState.S3.AccessKey.Value,
SecretKey: newState.S3.SecretKey.Value,
ServerSideEncryption: newState.S3.ServerSideEncryption.Value,
Endpoint: newState.S3.Endpoint.Value,
PathStyleAccess: newState.S3.PathStyleAccess.Value,
},
},
)
if err != nil {
response.Diagnostics.AddError(err.Error(), err.Error())
return
}

newState.ID = newState.Name

found, diags := r.read(newState.ID.Value, &newState)
response.Diagnostics.Append(diags...)
if response.Diagnostics.HasError() {
return
}
if !found {
response.Diagnostics.AddError(
"Failed to read snapshot repository after create.",
"Failed to read snapshot repository after create.",
)
response.State.RemoveResource(ctx)
return
}

// Finally, set the state
response.Diagnostics.Append(response.State.Set(ctx, newState)...)
}
54 changes: 54 additions & 0 deletions ec/ecresource/snapshotrepositoryresource/delete.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Licensed to Elasticsearch B.V. under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Elasticsearch B.V. licenses this file to you under
// the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

package snapshotrepositoryresource

import (
"context"

"github.com/hashicorp/terraform-plugin-framework/resource"

"github.com/elastic/cloud-sdk-go/pkg/api/apierror"
"github.com/elastic/cloud-sdk-go/pkg/api/platformapi/snaprepoapi"
)

// Delete will delete an existing snapshot repository
func (r *Resource) Delete(ctx context.Context, request resource.DeleteRequest, response *resource.DeleteResponse) {
if !resourceReady(r, &response.Diagnostics) {
return
}

var state modelV0

diags := request.State.Get(ctx, &state)
response.Diagnostics.Append(diags...)
if response.Diagnostics.HasError() {
return
}

err := snaprepoapi.Delete(snaprepoapi.DeleteParams{
API: r.client,
Region: "ece-region", // This resource is only usable for ECE installations. Thus, we can default to ece-region.
Name: state.Name.Value,
})
if err != nil {
if !apierror.IsRuntimeStatusCode(err, 404) {
response.Diagnostics.AddError(err.Error(), err.Error())
}
return
}
}
123 changes: 123 additions & 0 deletions ec/ecresource/snapshotrepositoryresource/read.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// Licensed to Elasticsearch B.V. under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Elasticsearch B.V. licenses this file to you under
// the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

package snapshotrepositoryresource

import (
"context"
"fmt"

"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/types"

"github.com/elastic/cloud-sdk-go/pkg/api/apierror"
"github.com/elastic/cloud-sdk-go/pkg/api/platformapi/snaprepoapi"
"github.com/elastic/cloud-sdk-go/pkg/models"
)

func (r *Resource) Read(ctx context.Context, request resource.ReadRequest, response *resource.ReadResponse) {
if !resourceReady(r, &response.Diagnostics) {
return
}

var newState modelV0

diags := request.State.Get(ctx, &newState)
response.Diagnostics.Append(diags...)
if response.Diagnostics.HasError() {
return
}

found, diags := r.read(newState.ID.Value, &newState)
response.Diagnostics.Append(diags...)
if response.Diagnostics.HasError() {
return
}
if !found {
response.State.RemoveResource(ctx)
return
}

// Finally, set the state
response.Diagnostics.Append(response.State.Set(ctx, newState)...)
}

func (r *Resource) read(id string, state *modelV0) (found bool, diags diag.Diagnostics) {
res, err := snaprepoapi.Get(snaprepoapi.GetParams{
API: r.client,
Region: "ece-region", // This resource is only usable for ECE installations. Thus, we can default to ece-region.
Name: id,
})
if err != nil {
if apierror.IsRuntimeStatusCode(err, 404) {
return false, diags
}
diags.AddError("failed reading snapshot repository", err.Error())
return true, diags
}

diags.Append(modelToState(res, state)...)
return true, diags
}

func modelToState(model *models.RepositoryConfig, state *modelV0) diag.Diagnostics {
var diags diag.Diagnostics

if model.RepositoryName != nil {
state.Name = types.String{Value: *model.RepositoryName}
}

config, _ := model.Config.(map[string]interface{})
if repositoryType, ok := config["type"]; ok && repositoryType != nil {
if settingsInterface, ok := config["settings"]; ok && settingsInterface != nil {
settings := settingsInterface.(map[string]interface{})
if repositoryType.(string) == "s3" {
if state.S3 == nil {
state.S3 = &s3RepositoryV0{}
}
if region, ok := settings["region"]; ok && region != nil {
state.S3.Region = types.String{Value: region.(string)}
}
if bucket, ok := settings["bucket"]; ok && bucket != nil {
state.S3.Bucket = types.String{Value: bucket.(string)}
}
if accessKey, ok := settings["access_key"]; ok && accessKey != nil {
state.S3.AccessKey = types.String{Value: accessKey.(string)}
}
if secretKey, ok := settings["secret_key"]; ok && secretKey != nil {
state.S3.SecretKey = types.String{Value: secretKey.(string)}
}
if serverSideEncryption, ok := settings["server_side_encryption"]; ok && serverSideEncryption != nil {
state.S3.ServerSideEncryption = types.Bool{Value: serverSideEncryption.(bool)}
}
if endpoint, ok := settings["endpoint"]; ok && endpoint != nil {
state.S3.Endpoint = types.String{Value: endpoint.(string)}
}
if pathStyleAccess, ok := settings["path_style_access"]; ok && pathStyleAccess != nil {
state.S3.PathStyleAccess = types.Bool{Value: pathStyleAccess.(bool)}
}
} else {
diags.AddError(
fmt.Sprintf("Unknown repository type %s", repositoryType.(string)),
fmt.Sprintf("The repository type %s is not supported", repositoryType.(string)),
)
}
}
}
return diags
}
Loading

0 comments on commit f33684d

Please sign in to comment.