Fix opslevel_service dropping preferred_api_document_source when api_document_path is unset (#14748)#647
Conversation
| resp.Diagnostics.AddError("opslevel client error", fmt.Sprintf("Unable to set provided 'api_document_path' %s with doc source '%s' for service. error: %s", apiDocPath, sourceEnum, err)) | ||
| return | ||
| } | ||
| if shouldUpdate, apiDocPath, sourceEnum := serviceApiDocSettingsUpdateInput(planModel, nil); shouldUpdate { |
There was a problem hiding this comment.
This issue exists within create too, though it's not as visible. We should update that as well.
There was a problem hiding this comment.
switched create over to use the same helper
| managesApiDocSource = managesApiDocSource || !state.PreferredApiDocumentSource.IsNull() | ||
| } | ||
| if !managesApiDocPath && !managesApiDocSource { | ||
| return false, "", nil |
There was a problem hiding this comment.
So within the rails api we have 3 states; nil (basically the clear state), set & omitted (no change), used to control both of these fields. Within terraform however we don't have that distinction, we only have set & null. Because of this we have to assume that both of these states will be explicitly managed.
The only scenario I can see us not wanting to send this api request in is one in which the state & plan values are equal.
There was a problem hiding this comment.
Makes sense ,added an equality short-circuit so we only skip when plan == state, plus tests to make sure real changes still go through.
Summary
Fixes #14748. Configuring
preferred_api_document_sourceonopslevel_servicewithout also settingapi_document_pathcaused apply to fail withProvider produced inconsistent result after apply: .preferred_api_document_source: was cty.StringVal("PUSH"), but now null. The provider was gating theserviceApiDocSettingsUpdatemutation behind a non-emptyapi_document_path, so the user's preferred-source value was never sent to the backend — Terraform's plan/state consistency check then rejected the apply.This is a provider-only fix. The GraphQL backend and
opslevel-goclient already accepted the two arguments independently; only the provider was incorrectly coupling them.Changes
serviceApiDocSettingsUpdateInput(plan, state)helper inopslevel/resource_opslevel_service.gothat decides when to callServiceApiDocSettingsUpdateand with what arguments. ReturnsshouldUpdate=truewhenever either field is configured in plan, or whenever either field was previously managed in state (so unsetting still works).Createnow uses the helper, fixing source-only configs.Updatenow uses the same helper, fixing the prior bug whereapi_document_pathbeing null silently clearedpreferred_api_document_source.Customer-reported repro
Before the fix:
terraform applyerrored with the inconsistent-result message and left an orphaned service in OpsLevel that Terraform did not record in state.After the fix: apply succeeds, and a follow-up
terraform planreportsNo changes.Test plan
serviceApiDocSettingsUpdateInputcovering source-only PUSH, source-only PULL, path-only, unmanaged, unset previously-managed source, and unset previously-managed path — seeopslevel/resource_opslevel_service_test.go.resource_service_create_with_preferred_api_document_source_without_pathreproducing the exact customer config and assertingapi_document_path == nullandpreferred_api_document_source == "PUSH"after apply — seetests/service.tftest.hcl.GOWORK=off go test ./opslevelpasses.GOWORK=off go vet ./...clean.GOWORK=off task testpasses (104 Terraform tests + Go unit tests).PUSHandPULLconfigs apply cleanly, idempotent on re-plan, and the resultingservicesrow in the database has the expectedapi_docs_sourcevalue withapi_docs_pathnull.