feat(users): add external to instance service account create and update
Closes #2310
GitLab 19.5 lets you set external when you create or update an instance service account (gitlab-org/gitlab!254608 (merged)). With client-go, Go users couldn't set it. The service accounts returned by ListServiceAccounts and UpdateInstanceServiceAccount also didn't say if they are external.
Now:
CreateServiceAccountUserOptionsandUpdateServiceAccountOptionshaveExternal.ServiceAccounthasExternal, so those two methods return it.
false matters here. GitLab creates service accounts as external by default, so to get a non-external one you have to send "external": false. client-go sends it when you set External: new(false).
UpdateServiceAccountOptionsis shared byGroups.UpdateServiceAccountandUsers.UpdateInstanceServiceAccount. I addedExternalthere instead of making a new options type. Changing theUpdateInstanceServiceAccountsignature would be a breaking change, and those wait for 4.0. The group endpoint doesn't acceptexternal, so GitLab ignores it there. The field comment says it's only forUpdateInstanceServiceAccount. I can switch to a separate options type if you prefer.- GitLab versions before 19.5 ignore the parameter.
I left the group and project service account responses out. external on them can go in a follow-up.
!3063 (closed) also edits the ServiceAccount struct, so one of the two may need a small rebase.
How I tested
I wrote a small Go program that creates a service account with External: new(false), updates it with External: new(true), and lists service accounts, all against a local test server. The server prints each request.
On main, the program doesn't compile:
unknown field External in struct literal of type gitlab.CreateServiceAccountUserOptions
unknown field External in struct literal of type gitlab.UpdateServiceAccountOptions
sa.External undefined (type *gitlab.ServiceAccount has no field or method External)
list[0].External undefined (type *gitlab.ServiceAccount has no field or method External)On this branch, false is sent, and External is read back from the update and list responses:
server got: POST /api/v4/service_accounts body={"username":"bot","external":false}
create err: <nil>
server got: PATCH /api/v4/service_accounts/7 body={"external":true}
update err=<nil> External=true
server got: GET /api/v4/service_accounts body=
list err=<nil> External=trueThe create unit test now checks the request body, including "external": false. I added an update test that checks the request body and the returned External, for true and false.
$ go test -count=1 -run 'ServiceAccount' .
ok gitlab.com/gitlab-org/api/client-go/v3 0.008sgofumpt -l on the changed files and go vet . printed nothing. I didn't run make reviewable, golangci-lint or the -race tests locally. The pipeline runs them.
I couldn't test against a real GitLab 19.5 instance. Creating an instance service account needs admin access, and I don't have such an instance.
Implemented with AI assistance; I reviewed and tested the changes.