func()

in ec/ecresource/deploymentresource/read.go [84:259]


func (r *Resource) read(ctx context.Context, id string, state *deploymentv2.DeploymentTF, plan *deploymentv2.DeploymentTF, deploymentResources []*models.DeploymentResource, privateFilters []string, readResponse *resource.ReadResponse) (*deploymentv2.Deployment, diag.Diagnostics) {
	var diags diag.Diagnostics

	var base deploymentv2.DeploymentTF

	switch {
	case plan != nil:
		base = *plan
	case state != nil:
		base = *state
	default:
		diags.AddError("both state and plan are empty", "please specify at least one of them")
		return nil, diags
	}

	response, err := deploymentapi.Get(deploymentapi.GetParams{
		API:          r.client,
		DeploymentID: id,
		QueryParams: deputil.QueryParams{
			ShowSettings:               true,
			ShowPlans:                  true,
			ShowMetadata:               true,
			ShowPlanDefaults:           true,
			ShowInstanceConfigurations: true,
		},
	})
	if err != nil {
		if deploymentNotFound(err) {
			diags.AddError("Deployment not found", err.Error())
			return nil, diags
		}
		diags.AddError("Deployment get error", err.Error())
		return nil, diags
	}

	if readResponse != nil {
		UpdatePrivateStateInstanceConfigurations(ctx, readResponse.Private, response.InstanceConfigurations)
	}

	if !HasRunningResources(response) {
		return nil, nil
	}

	if response.Resources == nil || len(response.Resources.Elasticsearch) == 0 {
		diags.AddError("Get resource error", "cannot find Elasticsearch in response resources")
		return nil, diags
	}

	if response.Resources.Elasticsearch[0].Info.PlanInfo.Current != nil && response.Resources.Elasticsearch[0].Info.PlanInfo.Current.Plan != nil {
		if err := checkVersion(response.Resources.Elasticsearch[0].Info.PlanInfo.Current.Plan.Elasticsearch.Version); err != nil {
			diags.AddError("Get resource error", err.Error())
			return nil, diags
		}
	}

	refId := ""

	var baseElasticsearch *elasticsearchv2.ElasticsearchTF

	if diags = tfsdk.ValueAs(ctx, base.Elasticsearch, &baseElasticsearch); diags.HasError() {
		return nil, diags
	}

	if baseElasticsearch != nil {
		refId = baseElasticsearch.RefId.ValueString()
	}

	remotes, err := esremoteclustersapi.Get(esremoteclustersapi.GetParams{
		API: r.client, DeploymentID: id,
		RefID: refId,
	})
	if err != nil {
		diags.AddError("Remote clusters read error", err.Error())
		return nil, diags
	}
	if remotes == nil {
		remotes = &models.RemoteResources{}
	}

	deployment, err := deploymentv2.ReadDeployment(response, remotes, deploymentResources)
	if err != nil {
		diags.AddError("Deployment read error", err.Error())
		return nil, diags
	}

	deployment.RequestId = base.RequestId.ValueString()
	if !base.ResetElasticsearchPassword.IsNull() && !base.ResetElasticsearchPassword.IsUnknown() {
		deployment.ResetElasticsearchPassword = base.ResetElasticsearchPassword.ValueBoolPointer()
	}

	if !base.MigrateToLatestHardware.IsNull() && !base.MigrateToLatestHardware.IsUnknown() {
		deployment.MigrateToLatestHardware = base.MigrateToLatestHardware.ValueBoolPointer()
	}

	diags.Append(deployment.IncludePrivateStateTrafficFilters(ctx, base, privateFilters)...)

	deployment.SetCredentialsIfEmpty(state)

	diags.Append(deployment.ProcessSelfInObservability(ctx, base)...)

	deployment.NullifyUnusedEsTopologies(ctx, baseElasticsearch)
	diags.Append(deployment.PersistSnapshotSource(ctx, baseElasticsearch)...)

	if !deployment.HasNodeTypes() {
		// The MigrateDeploymentTemplate request can only be performed for deployments that use node roles.
		// We'll skip this logic for deployments with node types.
		migrateTemplateRequest, err := r.client.V1API.Deployments.MigrateDeploymentTemplate(
			deployments.NewMigrateDeploymentTemplateParams().WithDeploymentID(deployment.Id).WithTemplateID(deployment.DeploymentTemplateId),
			r.client.AuthWriter,
		)

		if err != nil {
			diags.AddError("Template migrate request error", err.Error())
			return nil, diags
		}

		// Store migrate request in private state
		if readResponse != nil {
			UpdatePrivateStateMigrateTemplateRequest(ctx, readResponse.Private, migrateTemplateRequest)
		}

		deployment.SetLatestInstanceConfigInfo(migrateTemplateRequest)
	} else {
		// Set latest_instance_configuration_* fields to current values
		// If this isn't done, when migrating a deployment to node roles, these fields will contain inconsistent values
		deployment.SetLatestInstanceConfigInfoToCurrent()
	}

	// Set Elasticsearch `strategy` to the one from plan.
	// We don't care about backend current `strategy`'s value and should not trigger a change,
	// if the backend's value differs from the local state.
	if baseElasticsearch != nil && !baseElasticsearch.Strategy.IsNull() {
		deployment.Elasticsearch.Strategy = baseElasticsearch.Strategy.ValueStringPointer()
	}

	// sync Elasticsearch keystore contents if plan or state defines it:
	// - all keystore entries that are not managed by the resource are left alone
	// - if backend doesn't contain some keystore entry, the entry should be removed from the future state as well
	if baseElasticsearch != nil && deployment.Elasticsearch != nil && !baseElasticsearch.KeystoreContents.IsNull() {
		ds := baseElasticsearch.KeystoreContents.ElementsAs(ctx, &deployment.Elasticsearch.KeystoreContents, true)
		diags.Append(ds...)

		keystoreContents, err := eskeystoreapi.Get(eskeystoreapi.GetParams{
			API:          r.client,
			DeploymentID: id,
		})
		if err != nil {
			diags.AddError("Deployment keystore read error", err.Error())
			return nil, diags
		}

		for entryName, entryVal := range deployment.Elasticsearch.KeystoreContents {
			secret, ok := keystoreContents.Secrets[entryName]
			if !ok {
				delete(deployment.Elasticsearch.KeystoreContents, entryName)
				continue
			}
			if secret.AsFile != nil {
				entryVal.AsFile = secret.AsFile
				deployment.Elasticsearch.KeystoreContents[entryName] = entryVal
			}
		}
	}

	// ReadDeployment returns empty config struct if there is no config, so we have to nullify it if plan doesn't contain it
	// we use state for plan in Read and there is no state during import so we need to check elasticsearchPlan against nil
	if baseElasticsearch != nil &&
		baseElasticsearch.Config.IsNull() &&
		deployment.Elasticsearch != nil &&
		deployment.Elasticsearch.Config != nil &&
		deployment.Elasticsearch.Config.IsEmpty() {
		deployment.Elasticsearch.Config = nil
	}

	return deployment, diags
}