internal/elasticsearch/security/api_key/resource.go (75 lines of code) (raw):

package api_key import ( "context" "encoding/json" "github.com/elastic/terraform-provider-elasticstack/internal/clients" "github.com/elastic/terraform-provider-elasticstack/internal/utils" "github.com/hashicorp/go-version" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/resource" ) // Ensure provider defined types fully satisfy framework interfaces var _ resource.Resource = &Resource{} var _ resource.ResourceWithConfigure = &Resource{} var _ resource.ResourceWithUpgradeState = &Resource{} var ( MinVersion = version.Must(version.NewVersion("8.0.0")) // Enabled in 8.0 MinVersionWithUpdate = version.Must(version.NewVersion("8.4.0")) MinVersionReturningRoleDescriptors = version.Must(version.NewVersion("8.5.0")) MinVersionWithRestriction = version.Must(version.NewVersion("8.9.0")) // Enabled in 8.0 ) type Resource struct { client *clients.ApiClient } var configuredResources = []*Resource{} func (r *Resource) Configure(ctx context.Context, request resource.ConfigureRequest, response *resource.ConfigureResponse) { client, diags := clients.ConvertProviderData(request.ProviderData) response.Diagnostics.Append(diags...) r.client = client configuredResources = append(configuredResources, r) } func (r *Resource) Metadata(ctx context.Context, request resource.MetadataRequest, response *resource.MetadataResponse) { response.TypeName = request.ProviderTypeName + "_elasticsearch_security_api_key" } // Equivalent to privatestate.ProviderData type privateData interface { // GetKey returns the private state data associated with the given key. // // If the key is reserved for framework usage, an error diagnostic // is returned. If the key is valid, but private state data is not found, // nil is returned. // // The naming of keys only matters in context of a single resource, // however care should be taken that any historical keys are not reused // without accounting for older resource instances that may still have // older data at the key. GetKey(ctx context.Context, key string) ([]byte, diag.Diagnostics) // SetKey sets the private state data at the given key. // // If the key is reserved for framework usage, an error diagnostic // is returned. The data must be valid JSON and UTF-8 safe or an error // diagnostic is returned. // // The naming of keys only matters in context of a single resource, // however care should be taken that any historical keys are not reused // without accounting for older resource instances that may still have // older data at the key. SetKey(ctx context.Context, key string, value []byte) diag.Diagnostics } const clusterVersionPrivateDataKey = "cluster-version" type clusterVersionPrivateData struct { Version string } func (r *Resource) saveClusterVersion(ctx context.Context, client *clients.ApiClient, priv privateData) diag.Diagnostics { version, sdkDiags := client.ServerVersion(ctx) diags := utils.FrameworkDiagsFromSDK(sdkDiags) if diags.HasError() { return diags } data, err := json.Marshal(clusterVersionPrivateData{Version: version.String()}) if err != nil { diags.AddError("failed to marshal cluster version data", err.Error()) return diags } diags.Append(priv.SetKey(ctx, clusterVersionPrivateDataKey, data)...) return diags } func (r *Resource) clusterVersionOfLastRead(ctx context.Context, priv privateData) (*version.Version, diag.Diagnostics) { versionBytes, diags := priv.GetKey(ctx, clusterVersionPrivateDataKey) if diags.HasError() { return nil, diags } if versionBytes == nil { return nil, nil } var data clusterVersionPrivateData err := json.Unmarshal(versionBytes, &data) if err != nil { diags.AddError("failed to parse private data json", err.Error()) return nil, diags } v, err := version.NewVersion(data.Version) if err != nil { diags.AddError("failed to parse stored cluster version", err.Error()) return nil, diags } return v, diags }