ec/ecdatasource/deploymenttemplates/read.go (284 lines of code) (raw):

// 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 deploymenttemplates import ( "context" "fmt" "github.com/elastic/cloud-sdk-go/pkg/api/deploymentapi/deptemplateapi" "github.com/elastic/cloud-sdk-go/pkg/models" "github.com/elastic/terraform-provider-ec/ec/internal/util" "github.com/hashicorp/terraform-plugin-framework/datasource" ) func (d DataSource) Read(ctx context.Context, request datasource.ReadRequest, response *datasource.ReadResponse) { // Prevent panic if the provider has not been configured. if d.client == nil { response.Diagnostics.AddError( "Unconfigured API Client", "Expected configured API client. Please report this issue to the provider developers.", ) return } var data deploymentTemplatesDataSourceModel response.Diagnostics.Append(request.Config.Get(ctx, &data)...) res, err := deptemplateapi.List(deptemplateapi.ListParams{ API: d.client, MetadataFilter: "", Region: data.Region.ValueString(), StackVersion: data.StackVersion.ValueString(), ShowHidden: false, HideInstanceConfigurations: false, }) if err != nil { response.Diagnostics.AddError( "Failed retrieving deployment template list", fmt.Sprintf("Failed retrieving deployment template list: %s", err), ) return } showDeprecated := data.ShowDeprecated.ValueBool() filerById := data.Id.ValueString() data.Templates = mapResponseToModel(res, showDeprecated, filerById) // Finally, set the state diags := response.State.Set(ctx, data) response.Diagnostics.Append(diags...) } func mapResponseToModel(response []*models.DeploymentTemplateInfoV2, showDeprecated bool, idFilter string) []deploymentTemplateModel { templates := make([]deploymentTemplateModel, 0, len(response)) for _, template := range response { if idFilter != "" && *template.ID != idFilter { continue } // Templates hidden in the API are considered deprecated hidden := isHidden(template) if !showDeprecated && hidden { continue } instanceConfigurations := template.InstanceConfigurations icMap := make(map[string]models.InstanceConfigurationInfo) for _, ic := range instanceConfigurations { if ic != nil { icMap[ic.ID] = *ic } } templateDefinition := template.DeploymentTemplate templateModel := deploymentTemplateModel{ ID: *template.ID, Name: *template.Name, Description: template.Description, MinStackVersion: template.MinVersion, Deprecated: hidden, Elasticsearch: mapElasticsearch(templateDefinition, icMap), Kibana: mapKibana(templateDefinition, icMap), EnterpriseSearch: mapEnterpriseSearch(templateDefinition, icMap), Apm: mapApm(templateDefinition, icMap), IntegrationsServer: mapIntegrationsServer(templateDefinition, icMap), } templates = append(templates, templateModel) } return templates } func mapElasticsearch(templateDefinition *models.DeploymentCreateRequest, configurations map[string]models.InstanceConfigurationInfo) *elasticsearchModel { if templateDefinition == nil { return nil } resources := templateDefinition.Resources if resources == nil { return nil } payloads := resources.Elasticsearch if len(payloads) == 0 { return nil } firstEs := payloads[0] if firstEs.Plan == nil { return nil } es := elasticsearchModel{} es.Autoscale = firstEs.Plan.AutoscalingEnabled for _, element := range firstEs.Plan.ClusterTopology { size := element.Size id := element.InstanceConfigurationID topology := topologyModel{ InstanceConfigurationId: id, InstanceConfigurationVersion: element.InstanceConfigurationVersion, DefaultSize: util.MemoryToStateOptional(getSizeValue(size)), SizeResource: getSizeResource(size), AvailableSizes: collectAvailableSizes(configurations, id), Autoscaling: mapAutoscaling(element), } switch element.ID { case "hot_content": es.HotTier = &topology case "coordinating": es.CoordinatingTier = &topology case "master": es.MasterTier = &topology case "warm": es.WarmTier = &topology case "cold": es.ColdTier = &topology case "frozen": es.FrozenTier = &topology case "ml": es.MlTier = &topology } } return &es } func collectAvailableSizes(configurations map[string]models.InstanceConfigurationInfo, id string) []string { var availableSizes []string ic, found := configurations[id] if found { if ic.DiscreteSizes != nil { availableSizes = make([]string, 0) for _, size := range ic.DiscreteSizes.Sizes { availableSizes = append(availableSizes, util.MemoryToState(size)) } } } return availableSizes } func getSizeResource(size *models.TopologySize) *string { if size == nil { return nil } return size.Resource } func getSizeValue(size *models.TopologySize) *int32 { if size == nil { return nil } return size.Value } func mapAutoscaling(element *models.ElasticsearchClusterTopologyElement) autoscalingModel { model := autoscalingModel{} model.Autoscale = element.AutoscalingTierOverride if element.AutoscalingMin != nil { model.MinSizeResource = element.AutoscalingMin.Resource model.MinSize = util.MemoryToStateOptional(element.AutoscalingMin.Value) } if element.AutoscalingMax != nil { model.MaxSizeResource = element.AutoscalingMax.Resource model.MaxSize = util.MemoryToStateOptional(element.AutoscalingMax.Value) } return model } func mapKibana(templateDefinition *models.DeploymentCreateRequest, icMap map[string]models.InstanceConfigurationInfo) *statelessModel { if templateDefinition == nil { return nil } resources := templateDefinition.Resources if resources == nil { return nil } payloads := resources.Kibana if len(payloads) == 0 { return nil } firstKibana := payloads[0] if firstKibana.Plan == nil { return nil } topologies := firstKibana.Plan.ClusterTopology if len(topologies) == 0 { return nil } element := topologies[0] return &statelessModel{ InstanceConfigurationId: element.InstanceConfigurationID, InstanceConfigurationVersion: element.InstanceConfigurationVersion, DefaultSize: util.MemoryToStateOptional(getSizeValue(element.Size)), SizeResource: getSizeResource(element.Size), AvailableSizes: collectAvailableSizes(icMap, element.InstanceConfigurationID), } } func mapEnterpriseSearch(templateDefinition *models.DeploymentCreateRequest, icMap map[string]models.InstanceConfigurationInfo) *statelessModel { if templateDefinition == nil { return nil } resources := templateDefinition.Resources if resources == nil { return nil } payloads := resources.EnterpriseSearch if len(payloads) == 0 { return nil } firstEnterpriseSearch := payloads[0] if firstEnterpriseSearch.Plan == nil { return nil } topologies := firstEnterpriseSearch.Plan.ClusterTopology if len(topologies) == 0 { return nil } element := topologies[0] return &statelessModel{ InstanceConfigurationId: element.InstanceConfigurationID, InstanceConfigurationVersion: element.InstanceConfigurationVersion, DefaultSize: util.MemoryToStateOptional(getSizeValue(element.Size)), SizeResource: getSizeResource(element.Size), AvailableSizes: collectAvailableSizes(icMap, element.InstanceConfigurationID), } } func mapApm(templateDefinition *models.DeploymentCreateRequest, icMap map[string]models.InstanceConfigurationInfo) *statelessModel { if templateDefinition == nil { return nil } resources := templateDefinition.Resources if resources == nil { return nil } payloads := resources.Apm if len(payloads) == 0 { return nil } firstApm := payloads[0] if firstApm.Plan == nil { return nil } topologies := firstApm.Plan.ClusterTopology if len(topologies) == 0 { return nil } element := topologies[0] return &statelessModel{ InstanceConfigurationId: element.InstanceConfigurationID, InstanceConfigurationVersion: element.InstanceConfigurationVersion, DefaultSize: util.MemoryToStateOptional(getSizeValue(element.Size)), SizeResource: getSizeResource(element.Size), AvailableSizes: collectAvailableSizes(icMap, element.InstanceConfigurationID), } } func mapIntegrationsServer(templateDefinition *models.DeploymentCreateRequest, icMap map[string]models.InstanceConfigurationInfo) *statelessModel { if templateDefinition == nil { return nil } resources := templateDefinition.Resources if resources == nil { return nil } payloads := resources.IntegrationsServer if len(payloads) == 0 { return nil } firstIntegrationsServer := payloads[0] if firstIntegrationsServer.Plan == nil { return nil } topologies := firstIntegrationsServer.Plan.ClusterTopology if len(topologies) == 0 { return nil } element := topologies[0] return &statelessModel{ InstanceConfigurationId: element.InstanceConfigurationID, InstanceConfigurationVersion: element.InstanceConfigurationVersion, DefaultSize: util.MemoryToStateOptional(getSizeValue(element.Size)), SizeResource: getSizeResource(element.Size), AvailableSizes: collectAvailableSizes(icMap, element.InstanceConfigurationID), } } func isHidden(template *models.DeploymentTemplateInfoV2) bool { for _, metadatum := range template.Metadata { if *metadatum.Key == "hidden" && *metadatum.Value == "true" { return true } } return false }