internal/elasticsearch/security/api_key/create.go (89 lines of code) (raw):

package api_key import ( "context" "fmt" "strings" "github.com/elastic/terraform-provider-elasticstack/internal/clients" "github.com/elastic/terraform-provider-elasticstack/internal/clients/elasticsearch" "github.com/elastic/terraform-provider-elasticstack/internal/models" "github.com/elastic/terraform-provider-elasticstack/internal/utils" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) func (r Resource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { var planModel tfModel resp.Diagnostics.Append(req.Plan.Get(ctx, &planModel)...) if resp.Diagnostics.HasError() { return } client, diags := clients.MaybeNewApiClientFromFrameworkResource(ctx, planModel.ElasticsearchConnection, r.client) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { return } apiModel, diags := r.buildApiModel(ctx, planModel, client) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { return } putResponse, diags := elasticsearch.CreateApiKey(client, &apiModel) resp.Diagnostics.Append(diags...) if putResponse == nil || resp.Diagnostics.HasError() { return } id, sdkDiags := client.ID(ctx, putResponse.Id) resp.Diagnostics.Append(utils.FrameworkDiagsFromSDK(sdkDiags)...) if resp.Diagnostics.HasError() { return } planModel.ID = basetypes.NewStringValue(id.String()) planModel.populateFromCreate(*putResponse) resp.Diagnostics.Append(resp.State.Set(ctx, planModel)...) if resp.Diagnostics.HasError() { return } finalModel, diags := r.read(ctx, client, planModel) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { return } resp.Diagnostics.Append(resp.State.Set(ctx, *finalModel)...) } func (r Resource) buildApiModel(ctx context.Context, model tfModel, client *clients.ApiClient) (models.ApiKey, diag.Diagnostics) { apiModel, diags := model.toAPIModel() if diags.HasError() { return models.ApiKey{}, diags } hasRestriction := false keysWithRestrictions := []string{} for key, descriptor := range apiModel.RolesDescriptors { if descriptor.Restriction != nil { hasRestriction = true keysWithRestrictions = append(keysWithRestrictions, key) } } if hasRestriction { isSupported, diags := doesCurrentVersionSupportRestrictionOnApiKey(ctx, client) if diags.HasError() { return models.ApiKey{}, diags } if !isSupported { diags.AddAttributeError( path.Root("roles_descriptors"), "Specifying `restriction` on an API key role description is not supported in this version of Elasticsearch", fmt.Sprintf("Specifying `restriction` on an API key role description is not supported in this version of Elasticsearch. Role descriptor(s) %s", strings.Join(keysWithRestrictions, ", ")), ) return models.ApiKey{}, diags } } return apiModel, nil } func doesCurrentVersionSupportRestrictionOnApiKey(ctx context.Context, client *clients.ApiClient) (bool, diag.Diagnostics) { currentVersion, diags := client.ServerVersion(ctx) if diags.HasError() { return false, utils.FrameworkDiagsFromSDK(diags) } return currentVersion.GreaterThanOrEqual(MinVersionWithRestriction), nil }