mirror of
https://github.com/netbirdio/netbird.git
synced 2026-10-26 14:29:08 +01:00
[management] Check a provider's url and credential before saving it (#7301)
A bad upstream or key saved cleanly and surfaced minutes later as a failed request or an empty model picker, with nothing pointing back at the record. CreateProvider now spends the credential once against the vendor's model listing. UpdateProvider does the same when the upstream, the key, the catalog provider or the skip-TLS flag changed — only then, so renames and price edits neither wait on a vendor nor fail because one is down. Both run before the store write, so a rejected rotation leaves the working key where it was. What cannot be checked still saves: no listing endpoint, no derivable Bedrock control-plane host, a private upstream, a record skipping TLS verification. Everything else blocks, outages included — 5xx, 429 and timeouts leave the record unverified just as a refusal does. Refusals return 422 and carry no status code or echoed URL. Discovery now reads as a partial edit, so a retyped URL can be listed against without also rotating the credential. Entries with their own listing host (Bedrock) get their configured upstream resolved separately, since a successful listing said nothing about it.
This commit is contained in:
@@ -26,6 +26,10 @@ type bootstrapFixture struct {
|
||||
manager Manager
|
||||
store store.Store
|
||||
perms *permissions.MockManager
|
||||
// vendor stands in for the provider credential check's vendor call, which
|
||||
// runs on every provider write. Without it these tests would reach a real
|
||||
// vendor to save a record.
|
||||
vendor *stubLister
|
||||
}
|
||||
|
||||
func newBootstrapFixture(t *testing.T) *bootstrapFixture {
|
||||
@@ -47,10 +51,12 @@ func newBootstrapFixture(t *testing.T) *bootstrapFixture {
|
||||
accounts.EXPECT().UpdateAccountPeers(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
|
||||
accounts.EXPECT().BufferUpdateAccountPeers(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
|
||||
|
||||
vendor := &stubLister{}
|
||||
return &bootstrapFixture{
|
||||
manager: NewManager(st, perms, accounts, nil),
|
||||
manager: NewManager(st, perms, accounts, nil, WithModelLister(vendor)),
|
||||
store: st,
|
||||
perms: perms,
|
||||
vendor: vendor,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,6 +217,7 @@ func TestCreateProviderHasNoSettingsSideEffects(t *testing.T) {
|
||||
f.expectPermission("account1", "user1", modules.AgentNetworkProviders, operations.Create, true)
|
||||
|
||||
provider := types.NewProvider("account1")
|
||||
provider.ProviderID = "openai_api"
|
||||
provider.Name = "openai"
|
||||
provider.UpstreamURL = "https://api.openai.com"
|
||||
provider.APIKey = "sk-test"
|
||||
|
||||
Reference in New Issue
Block a user