mirror of
https://github.com/netbirdio/netbird.git
synced 2026-10-07 22:19:08 +02:00
[management] delete targets when deleting exposed service (#6442)
This commit is contained in:
@@ -918,6 +918,10 @@ func (m *Manager) DeleteAllServices(ctx context.Context, accountID, userID strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, svc := range services {
|
for _, svc := range services {
|
||||||
|
if err = transaction.DeleteServiceTargets(ctx, accountID, svc.ID); err != nil {
|
||||||
|
return fmt.Errorf("failed to delete service targets: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
if err = transaction.DeleteService(ctx, accountID, svc.ID); err != nil {
|
if err = transaction.DeleteService(ctx, accountID, svc.ID); err != nil {
|
||||||
return fmt.Errorf("failed to delete service: %w", err)
|
return fmt.Errorf("failed to delete service: %w", err)
|
||||||
}
|
}
|
||||||
@@ -1270,6 +1274,10 @@ func (m *Manager) deletePeerService(ctx context.Context, accountID, peerID, serv
|
|||||||
return status.Errorf(status.PermissionDenied, "cannot delete service exposed by another peer")
|
return status.Errorf(status.PermissionDenied, "cannot delete service exposed by another peer")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err = transaction.DeleteServiceTargets(ctx, accountID, serviceID); err != nil {
|
||||||
|
return fmt.Errorf("delete service targets: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
if err = transaction.DeleteService(ctx, accountID, serviceID); err != nil {
|
if err = transaction.DeleteService(ctx, accountID, serviceID); err != nil {
|
||||||
return fmt.Errorf("delete service: %w", err)
|
return fmt.Errorf("delete service: %w", err)
|
||||||
}
|
}
|
||||||
@@ -1319,6 +1327,10 @@ func (m *Manager) deleteExpiredPeerService(ctx context.Context, accountID, peerI
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err = transaction.DeleteServiceTargets(ctx, accountID, serviceID); err != nil {
|
||||||
|
return fmt.Errorf("delete service targets: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
if err = transaction.DeleteService(ctx, accountID, serviceID); err != nil {
|
if err = transaction.DeleteService(ctx, accountID, serviceID); err != nil {
|
||||||
return fmt.Errorf("delete service: %w", err)
|
return fmt.Errorf("delete service: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -458,6 +458,9 @@ func TestDeletePeerService_SourcePeerValidation(t *testing.T) {
|
|||||||
txMock.EXPECT().
|
txMock.EXPECT().
|
||||||
GetServiceByID(ctx, store.LockingStrengthUpdate, accountID, serviceID).
|
GetServiceByID(ctx, store.LockingStrengthUpdate, accountID, serviceID).
|
||||||
Return(newEphemeralService(), nil)
|
Return(newEphemeralService(), nil)
|
||||||
|
txMock.EXPECT().
|
||||||
|
DeleteServiceTargets(ctx, accountID, serviceID).
|
||||||
|
Return(nil)
|
||||||
txMock.EXPECT().
|
txMock.EXPECT().
|
||||||
DeleteService(ctx, accountID, serviceID).
|
DeleteService(ctx, accountID, serviceID).
|
||||||
Return(nil)
|
Return(nil)
|
||||||
@@ -560,6 +563,9 @@ func TestDeletePeerService_SourcePeerValidation(t *testing.T) {
|
|||||||
txMock.EXPECT().
|
txMock.EXPECT().
|
||||||
GetServiceByID(ctx, store.LockingStrengthUpdate, accountID, serviceID).
|
GetServiceByID(ctx, store.LockingStrengthUpdate, accountID, serviceID).
|
||||||
Return(newEphemeralService(), nil)
|
Return(newEphemeralService(), nil)
|
||||||
|
txMock.EXPECT().
|
||||||
|
DeleteServiceTargets(ctx, accountID, serviceID).
|
||||||
|
Return(nil)
|
||||||
txMock.EXPECT().
|
txMock.EXPECT().
|
||||||
DeleteService(ctx, accountID, serviceID).
|
DeleteService(ctx, accountID, serviceID).
|
||||||
Return(nil)
|
Return(nil)
|
||||||
@@ -604,6 +610,9 @@ func TestDeletePeerService_SourcePeerValidation(t *testing.T) {
|
|||||||
txMock.EXPECT().
|
txMock.EXPECT().
|
||||||
GetServiceByID(ctx, store.LockingStrengthUpdate, accountID, serviceID).
|
GetServiceByID(ctx, store.LockingStrengthUpdate, accountID, serviceID).
|
||||||
Return(newEphemeralService(), nil)
|
Return(newEphemeralService(), nil)
|
||||||
|
txMock.EXPECT().
|
||||||
|
DeleteServiceTargets(ctx, accountID, serviceID).
|
||||||
|
Return(nil)
|
||||||
txMock.EXPECT().
|
txMock.EXPECT().
|
||||||
DeleteService(ctx, accountID, serviceID).
|
DeleteService(ctx, accountID, serviceID).
|
||||||
Return(nil)
|
Return(nil)
|
||||||
@@ -1192,6 +1201,67 @@ func TestDeleteService_DeletesTargets(t *testing.T) {
|
|||||||
assert.Len(t, targets, 0, "All targets should be deleted when service is deleted")
|
assert.Len(t, targets, 0, "All targets should be deleted when service is deleted")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDeleteExpiredPeerService_DeletesTargets(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
mgr, testStore := setupIntegrationTest(t)
|
||||||
|
|
||||||
|
resp, err := mgr.CreateServiceFromPeer(ctx, testAccountID, testPeerID, &rpservice.ExposeServiceRequest{
|
||||||
|
Port: 8080,
|
||||||
|
Mode: "http",
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
svcID := resolveServiceIDByDomain(t, testStore, resp.Domain)
|
||||||
|
|
||||||
|
targets, err := testStore.GetTargetsByServiceID(ctx, store.LockingStrengthNone, testAccountID, svcID)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Len(t, targets, 1, "ephemeral peer-exposed service should have exactly one persisted target before reaping")
|
||||||
|
|
||||||
|
expireEphemeralService(t, testStore, testAccountID, resp.Domain)
|
||||||
|
err = mgr.deleteExpiredPeerService(ctx, testAccountID, testPeerID, svcID)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
_, err = testStore.GetServiceByDomain(ctx, resp.Domain)
|
||||||
|
require.Error(t, err, "expired peer-exposed service should be deleted")
|
||||||
|
s, ok := status.FromError(err)
|
||||||
|
require.True(t, ok)
|
||||||
|
assert.Equal(t, status.NotFound, s.Type())
|
||||||
|
|
||||||
|
targets, err = testStore.GetTargetsByServiceID(ctx, store.LockingStrengthNone, testAccountID, svcID)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Len(t, targets, 0, "orphaned target rows must be deleted when an expired peer-exposed service is reaped")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDeleteServiceFromPeer_DeletesTargets(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
mgr, testStore := setupIntegrationTest(t)
|
||||||
|
|
||||||
|
resp, err := mgr.CreateServiceFromPeer(ctx, testAccountID, testPeerID, &rpservice.ExposeServiceRequest{
|
||||||
|
Port: 8080,
|
||||||
|
Mode: "http",
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
svcID := resolveServiceIDByDomain(t, testStore, resp.Domain)
|
||||||
|
|
||||||
|
targets, err := testStore.GetTargetsByServiceID(ctx, store.LockingStrengthNone, testAccountID, svcID)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Len(t, targets, 1, "ephemeral peer-exposed service should have exactly one persisted target before stopping")
|
||||||
|
|
||||||
|
err = mgr.StopServiceFromPeer(ctx, testAccountID, testPeerID, svcID)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
_, err = testStore.GetServiceByDomain(ctx, resp.Domain)
|
||||||
|
require.Error(t, err, "stopped peer-exposed service should be deleted")
|
||||||
|
s, ok := status.FromError(err)
|
||||||
|
require.True(t, ok)
|
||||||
|
assert.Equal(t, status.NotFound, s.Type())
|
||||||
|
|
||||||
|
targets, err = testStore.GetTargetsByServiceID(ctx, store.LockingStrengthNone, testAccountID, svcID)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Len(t, targets, 0, "orphaned target rows must be deleted when a peer stops its exposed service")
|
||||||
|
}
|
||||||
|
|
||||||
func TestValidateProtocolChange(t *testing.T) {
|
func TestValidateProtocolChange(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
|
|||||||
Reference in New Issue
Block a user