Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ func TestReapExpiredExposes(t *testing.T) {
mgr.exposeReaper.reapExpiredExposes(ctx)

// Expired service should be deleted
_, err = testStore.GetServiceByDomain(ctx, testAccountID, resp.Domain)
_, err = testStore.GetServiceByDomain(ctx, resp.Domain)
require.Error(t, err, "expired service should be deleted")

// Non-expired service should remain
_, err = testStore.GetServiceByDomain(ctx, testAccountID, resp2.Domain)
_, err = testStore.GetServiceByDomain(ctx, resp2.Domain)
require.NoError(t, err, "active service should remain")
}

Expand Down Expand Up @@ -191,14 +191,14 @@ func TestReapSkipsRenewedService(t *testing.T) {
// Reaper should skip it because the re-check sees a fresh timestamp
mgr.exposeReaper.reapExpiredExposes(ctx)

_, err = testStore.GetServiceByDomain(ctx, testAccountID, resp.Domain)
_, err = testStore.GetServiceByDomain(ctx, resp.Domain)
require.NoError(t, err, "renewed service should survive reaping")
}

// expireEphemeralService backdates meta_last_renewed_at to force expiration.
func expireEphemeralService(t *testing.T, s store.Store, accountID, domain string) {
t.Helper()
svc, err := s.GetServiceByDomain(context.Background(), accountID, domain)
svc, err := s.GetServiceByDomain(context.Background(), domain)
require.NoError(t, err)

expired := time.Now().Add(-2 * exposeTTL)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ func (m *Manager) initializeServiceForCreate(ctx context.Context, accountID stri

func (m *Manager) persistNewService(ctx context.Context, accountID string, service *service.Service) error {
return m.store.ExecuteInTransaction(ctx, func(transaction store.Store) error {
if err := m.checkDomainAvailable(ctx, transaction, accountID, service.Domain, ""); err != nil {
if err := m.checkDomainAvailable(ctx, transaction, service.Domain, ""); err != nil {
return err
}

Expand Down Expand Up @@ -245,7 +245,7 @@ func (m *Manager) persistNewEphemeralService(ctx context.Context, accountID, pee
return status.Errorf(status.PreconditionFailed, "peer has reached the maximum number of active expose sessions (%d)", maxExposesPerPeer)
}

if err := m.checkDomainAvailable(ctx, transaction, accountID, svc.Domain, ""); err != nil {
if err := m.checkDomainAvailable(ctx, transaction, svc.Domain, ""); err != nil {
return err
}

Expand All @@ -261,8 +261,8 @@ func (m *Manager) persistNewEphemeralService(ctx context.Context, accountID, pee
})
}

func (m *Manager) checkDomainAvailable(ctx context.Context, transaction store.Store, accountID, domain, excludeServiceID string) error {
existingService, err := transaction.GetServiceByDomain(ctx, accountID, domain)
func (m *Manager) checkDomainAvailable(ctx context.Context, transaction store.Store, domain, excludeServiceID string) error {
existingService, err := transaction.GetServiceByDomain(ctx, domain)
if err != nil {
if sErr, ok := status.FromError(err); !ok || sErr.Type() != status.NotFound {
return fmt.Errorf("failed to check existing service: %w", err)
Expand All @@ -271,7 +271,7 @@ func (m *Manager) checkDomainAvailable(ctx context.Context, transaction store.St
}

if existingService != nil && existingService.ID != excludeServiceID {
return status.Errorf(status.AlreadyExists, "service with domain %s already exists", domain)
return status.Errorf(status.AlreadyExists, "domain already taken")
}

return nil
Expand Down Expand Up @@ -352,7 +352,7 @@ func (m *Manager) persistServiceUpdate(ctx context.Context, accountID string, se
}

func (m *Manager) handleDomainChange(ctx context.Context, transaction store.Store, accountID string, service *service.Service) error {
if err := m.checkDomainAvailable(ctx, transaction, accountID, service.Domain, service.ID); err != nil {
if err := m.checkDomainAvailable(ctx, transaction, service.Domain, service.ID); err != nil {
return err
}

Expand Down Expand Up @@ -805,7 +805,7 @@ func (m *Manager) deleteServiceFromPeer(ctx context.Context, accountID, peerID,

// lookupPeerService finds a peer-initiated service by domain and validates ownership.
func (m *Manager) lookupPeerService(ctx context.Context, accountID, peerID, domain string) (*service.Service, error) {
svc, err := m.store.GetServiceByDomain(ctx, accountID, domain)
svc, err := m.store.GetServiceByDomain(ctx, domain)
if err != nil {
return nil, err
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ func TestInitializeServiceForCreate(t *testing.T) {

func TestCheckDomainAvailable(t *testing.T) {
ctx := context.Background()
accountID := "test-account"

tests := []struct {
name string
Expand All @@ -88,7 +87,7 @@ func TestCheckDomainAvailable(t *testing.T) {
excludeServiceID: "",
setupMock: func(ms *store.MockStore) {
ms.EXPECT().
GetServiceByDomain(ctx, accountID, "available.com").
GetServiceByDomain(ctx, "available.com").
Return(nil, status.Errorf(status.NotFound, "not found"))
},
expectedError: false,
Expand All @@ -99,7 +98,7 @@ func TestCheckDomainAvailable(t *testing.T) {
excludeServiceID: "",
setupMock: func(ms *store.MockStore) {
ms.EXPECT().
GetServiceByDomain(ctx, accountID, "exists.com").
GetServiceByDomain(ctx, "exists.com").
Return(&rpservice.Service{ID: "existing-id", Domain: "exists.com"}, nil)
},
expectedError: true,
Expand All @@ -111,7 +110,7 @@ func TestCheckDomainAvailable(t *testing.T) {
excludeServiceID: "service-123",
setupMock: func(ms *store.MockStore) {
ms.EXPECT().
GetServiceByDomain(ctx, accountID, "exists.com").
GetServiceByDomain(ctx, "exists.com").
Return(&rpservice.Service{ID: "service-123", Domain: "exists.com"}, nil)
},
expectedError: false,
Expand All @@ -122,7 +121,7 @@ func TestCheckDomainAvailable(t *testing.T) {
excludeServiceID: "service-456",
setupMock: func(ms *store.MockStore) {
ms.EXPECT().
GetServiceByDomain(ctx, accountID, "exists.com").
GetServiceByDomain(ctx, "exists.com").
Return(&rpservice.Service{ID: "service-123", Domain: "exists.com"}, nil)
},
expectedError: true,
Expand All @@ -134,7 +133,7 @@ func TestCheckDomainAvailable(t *testing.T) {
excludeServiceID: "",
setupMock: func(ms *store.MockStore) {
ms.EXPECT().
GetServiceByDomain(ctx, accountID, "error.com").
GetServiceByDomain(ctx, "error.com").
Return(nil, errors.New("database error"))
},
expectedError: true,
Expand All @@ -150,7 +149,7 @@ func TestCheckDomainAvailable(t *testing.T) {
tt.setupMock(mockStore)

mgr := &Manager{}
err := mgr.checkDomainAvailable(ctx, mockStore, accountID, tt.domain, tt.excludeServiceID)
err := mgr.checkDomainAvailable(ctx, mockStore, tt.domain, tt.excludeServiceID)

if tt.expectedError {
require.Error(t, err)
Expand All @@ -168,19 +167,18 @@ func TestCheckDomainAvailable(t *testing.T) {

func TestCheckDomainAvailable_EdgeCases(t *testing.T) {
ctx := context.Background()
accountID := "test-account"

t.Run("empty domain", func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

mockStore := store.NewMockStore(ctrl)
mockStore.EXPECT().
GetServiceByDomain(ctx, accountID, "").
GetServiceByDomain(ctx, "").
Return(nil, status.Errorf(status.NotFound, "not found"))

mgr := &Manager{}
err := mgr.checkDomainAvailable(ctx, mockStore, accountID, "", "")
err := mgr.checkDomainAvailable(ctx, mockStore, "", "")

assert.NoError(t, err)
})
Expand All @@ -191,11 +189,11 @@ func TestCheckDomainAvailable_EdgeCases(t *testing.T) {

mockStore := store.NewMockStore(ctrl)
mockStore.EXPECT().
GetServiceByDomain(ctx, accountID, "test.com").
GetServiceByDomain(ctx, "test.com").
Return(&rpservice.Service{ID: "some-id", Domain: "test.com"}, nil)

mgr := &Manager{}
err := mgr.checkDomainAvailable(ctx, mockStore, accountID, "test.com", "")
err := mgr.checkDomainAvailable(ctx, mockStore, "test.com", "")

assert.Error(t, err)
sErr, ok := status.FromError(err)
Expand All @@ -209,11 +207,11 @@ func TestCheckDomainAvailable_EdgeCases(t *testing.T) {

mockStore := store.NewMockStore(ctrl)
mockStore.EXPECT().
GetServiceByDomain(ctx, accountID, "nil.com").
GetServiceByDomain(ctx, "nil.com").
Return(nil, nil)

mgr := &Manager{}
err := mgr.checkDomainAvailable(ctx, mockStore, accountID, "nil.com", "")
err := mgr.checkDomainAvailable(ctx, mockStore, "nil.com", "")

assert.NoError(t, err)
})
Expand Down Expand Up @@ -241,7 +239,7 @@ func TestPersistNewService(t *testing.T) {
// Create another mock for the transaction
txMock := store.NewMockStore(ctrl)
txMock.EXPECT().
GetServiceByDomain(ctx, accountID, "new.com").
GetServiceByDomain(ctx, "new.com").
Return(nil, status.Errorf(status.NotFound, "not found"))
txMock.EXPECT().
CreateService(ctx, service).
Expand Down Expand Up @@ -272,7 +270,7 @@ func TestPersistNewService(t *testing.T) {
DoAndReturn(func(ctx context.Context, fn func(store.Store) error) error {
txMock := store.NewMockStore(ctrl)
txMock.EXPECT().
GetServiceByDomain(ctx, accountID, "existing.com").
GetServiceByDomain(ctx, "existing.com").
Return(&rpservice.Service{ID: "other-id", Domain: "existing.com"}, nil)

return fn(txMock)
Expand Down Expand Up @@ -814,7 +812,7 @@ func TestCreateServiceFromPeer(t *testing.T) {
assert.NotEmpty(t, resp.ServiceURL, "service URL should be set")

// Verify service is persisted in store
persisted, err := testStore.GetServiceByDomain(ctx, testAccountID, resp.Domain)
persisted, err := testStore.GetServiceByDomain(ctx, resp.Domain)
require.NoError(t, err)
assert.Equal(t, resp.Domain, persisted.Domain)
assert.Equal(t, rpservice.SourceEphemeral, persisted.Source, "source should be ephemeral")
Expand Down Expand Up @@ -977,7 +975,7 @@ func TestDeleteServiceFromPeer_ByDomain(t *testing.T) {
require.NoError(t, err)

// Verify service is deleted
_, err = testStore.GetServiceByDomain(ctx, testAccountID, resp.Domain)
_, err = testStore.GetServiceByDomain(ctx, resp.Domain)
require.Error(t, err, "service should be deleted")
})

Expand Down Expand Up @@ -1012,7 +1010,7 @@ func TestStopServiceFromPeer(t *testing.T) {
err = mgr.StopServiceFromPeer(ctx, testAccountID, testPeerID, resp.Domain)
require.NoError(t, err)

_, err = testStore.GetServiceByDomain(ctx, testAccountID, resp.Domain)
_, err = testStore.GetServiceByDomain(ctx, resp.Domain)
require.Error(t, err, "service should be deleted")
})
}
Expand All @@ -1031,7 +1029,7 @@ func TestDeleteService_DeletesEphemeralExpose(t *testing.T) {
require.NoError(t, err)
assert.Equal(t, int64(1), count, "one ephemeral service should exist after create")

svc, err := testStore.GetServiceByDomain(ctx, testAccountID, resp.Domain)
svc, err := testStore.GetServiceByDomain(ctx, resp.Domain)
require.NoError(t, err)

err = mgr.DeleteService(ctx, testAccountID, testUserID, svc.ID)
Expand Down
20 changes: 10 additions & 10 deletions management/internals/modules/reverseproxy/service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ type Service struct {
ID string `gorm:"primaryKey"`
AccountID string `gorm:"index"`
Name string
Domain string `gorm:"index"`
Domain string `gorm:"type:varchar(255);uniqueIndex"`
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Mirror the new domain length limit in Validate().

Line 137 now caps the column at 255 characters, but Validate() still only checks that Domain is non-empty. Overlong values will fail later with a DB error instead of a validation error.

💡 Proposed fix
 func (s *Service) Validate() error {
 	if s.Name == "" {
 		return errors.New("service name is required")
 	}
 	if len(s.Name) > 255 {
 		return errors.New("service name exceeds maximum length of 255 characters")
 	}
 
 	if s.Domain == "" {
 		return errors.New("service domain is required")
 	}
+	if len(s.Domain) > 255 {
+		return errors.New("service domain exceeds maximum length of 255 characters")
+	}
 
 	if len(s.Targets) == 0 {
 		return errors.New("at least one target is required")
 	}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Domain string `gorm:"type:varchar(255);uniqueIndex"`
func (s *Service) Validate() error {
if s.Name == "" {
return errors.New("service name is required")
}
if len(s.Name) > 255 {
return errors.New("service name exceeds maximum length of 255 characters")
}
if s.Domain == "" {
return errors.New("service domain is required")
}
if len(s.Domain) > 255 {
return errors.New("service domain exceeds maximum length of 255 characters")
}
if len(s.Targets) == 0 {
return errors.New("at least one target is required")
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@management/internals/modules/reverseproxy/service/service.go` at line 137,
The Domain struct tag now limits Domain to 255 chars but Validate() only checks
non-empty, so update the Validate() method (on the service struct/type that
defines Domain and includes a Validate() func) to also enforce max length 255
for Domain (e.g., check len(s.Domain) > 255 and return a validation error). Use
the same 255 value used in the gorm tag (or extract to a constant like
domainMaxLen used by the Domain field and Validate()) so database and validation
rules stay in sync.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, let's locate and examine the files mentioned in the review
find . -type f -name "service.go" | grep -i reverseproxy

Repository: netbirdio/netbird

Length of output: 123


🏁 Script executed:

# Look for sql_store.go
find . -type f -name "sql_store.go"

Repository: netbirdio/netbird

Length of output: 147


🏁 Script executed:

# Search for rpservice.Service or similar to understand the structure
rg -t go "type Service struct" --max-count 5

Repository: netbirdio/netbird

Length of output: 260


🌐 Web query:

GORM v2 AutoMigrate index to uniqueIndex upgrade behavior

💡 Result:

In GORM v2, AutoMigrate is not an “alter everything to match tags” schema diff. It mainly creates what’s missing (tables/columns/indexes/constraints) and won’t reliably “upgrade” an existing non-unique index into a unique one for you. (gorm.io)

What happens if you change gorm:"index"gorm:"uniqueIndex"

  • If a non-unique index already exists, AutoMigrate will typically try to create a new unique index (often with a different name), and leave the old non-unique index in place (because it doesn’t treat that as a “missing index” vs “needs alteration” case). (gorm.io)
  • In some cases, name-resolution/matching issues can cause repeated creation of additional unique indexes on subsequent runs (e.g., name, then name_2, name_3, …). (github.com)
  • Depending on dialect/driver versions and the generated names, you may also see attempts to drop or reference a constraint/index name that doesn’t exist, due to mismatches between what GORM expects and what’s actually in the DB. (stackoverflow.com)

Practical takeaway / recommended migration approach

If you truly need to “upgrade” to unique, do it as an explicit migration:

  1. Drop the old non-unique index (by its real DB name).
  2. Create the new unique index (preferably with an explicit, stable name via uniqueIndex:your_name).
  3. Then AutoMigrate can keep doing additive changes safely. (gorm.io)

Citations:


🏁 Script executed:

# Read the Service struct definition in reverseproxy service
cat -n ./management/internals/modules/reverseproxy/service/service.go | head -150

Repository: netbirdio/netbird

Length of output: 5737


🏁 Script executed:

# Check the sql_store.go file at lines 129-137
cat -n ./management/server/store/sql_store.go | sed -n '120,150p'

Repository: netbirdio/netbird

Length of output: 1705


🏁 Script executed:

# Search for any explicit migrations related to Service or rpservice
rg -t go "type.*Migration|func.*[Mm]igrate.*Service|rpservice" --max-count 10

Repository: netbirdio/netbird

Length of output: 10390


🏁 Script executed:

# Check git history for changes to the Domain field index tag
cd ./management/internals/modules/reverseproxy/service && git log -p --follow -S "index\|uniqueIndex" -- service.go | head -100

Repository: netbirdio/netbird

Length of output: 43


🏁 Script executed:

# Search for migratePostAuto and migratePreAuto functions
rg -t go "func.*migratePostAuto|func.*migratePreAuto" -A 20

Repository: netbirdio/netbird

Length of output: 2638


🏁 Script executed:

# Look for migration files that might handle Service table or Domain index
find . -type f -name "*migrat*" | grep -v node_modules | grep -v ".git"

Repository: netbirdio/netbird

Length of output: 373


🏁 Script executed:

# Search for any explicit migration code handling indexes on Domain field
rg -t go "Domain.*uniqueIndex|Domain.*index|ALTER.*Domain|DROP.*index" -B 2 -A 2

Repository: netbirdio/netbird

Length of output: 3072


🏁 Script executed:

# Check git log with broader context to see if index tag was changed
git log --oneline --follow -- ./management/internals/modules/reverseproxy/service/service.go | head -20

Repository: netbirdio/netbird

Length of output: 91


🏁 Script executed:

# Get the full getMigrationsPostAuto function to see all migrations
rg -t go "func getMigrationsPostAuto" -A 100 management/server/store/store.go

Repository: netbirdio/netbird

Length of output: 2999


🏁 Script executed:

# Check if there's a migration for Service Domain index
rg -t go "Service.*Domain|rpservice.*migration" management/server/migration/migration.go

Repository: netbirdio/netbird

Length of output: 43


🏁 Script executed:

# Check the git commit that updated the type
git show ccbd554b --stat

Repository: netbirdio/netbird

Length of output: 50374


🏁 Script executed:

# Search for any recent Service-related migrations
rg -t go "Service\|rpservice" management/server/migration/migration.go

Repository: netbirdio/netbird

Length of output: 43


🏁 Script executed:

# Search for any migrations explicitly handling Service or Domain
rg -t go "Service|Domain|rpservice" management/server/migration/migration.go -B 2 -A 2

Repository: netbirdio/netbird

Length of output: 43


🏁 Script executed:

# Look at the full migration.go file to see all available migration helpers
wc -l management/server/migration/migration.go

Repository: netbirdio/netbird

Length of output: 105


🏁 Script executed:

# Check migration package for index-related functions
rg -t go "CreateIndexIfNotExists|DropIndex" management/server/migration/migration.go

Repository: netbirdio/netbird

Length of output: 394


🏁 Script executed:

# See if there are any Service-related migrations in post-auto
rg -t go "Service\|Domain" management/server/store/store.go | grep -i migrat

Repository: netbirdio/netbird

Length of output: 43


🏁 Script executed:

# Check git diff for recent changes to the Domain field
git diff HEAD~10..HEAD -- management/internals/modules/reverseproxy/service/service.go 2>/dev/null || echo "Not enough history or file unchanged recently"

Repository: netbirdio/netbird

Length of output: 106


🏁 Script executed:

# Read the migration.go file to understand available helpers
cat -n management/server/migration/migration.go | head -100

Repository: netbirdio/netbird

Length of output: 3597


🏁 Script executed:

# Look for the full CreateIndexIfNotExists function implementation
rg -t go "func CreateIndexIfNotExists" -A 30 management/server/migration/migration.go

Repository: netbirdio/netbird

Length of output: 1028


🏁 Script executed:

# Check if there's any explicit migration for Service Domain
rg -t go "Domain\|rpservice\.Service" management/server/migration/migration.go

Repository: netbirdio/netbird

Length of output: 43


🏁 Script executed:

# Search for any existing migrations that might handle Service or reverse proxy
find . -type f -name "*.go" -path "*/migration*" -exec grep -l "rpservice\|Service.*Domain" {} \;

Repository: netbirdio/netbird

Length of output: 43


Add an explicit migration to handle the Domain field index change.

GORM v2's AutoMigrate does not reliably convert existing non-unique indexes to unique ones. When the Domain field tag changes from gorm:"index" to gorm:"uniqueIndex", AutoMigrate may create a new unique index while leaving the old non-unique one in place, resulting in duplicate indexes without enforcing the uniqueness guarantee on existing data.

Add an explicit migration in getMigrationsPostAuto() (management/server/store/store.go) to:

  1. Drop the old non-unique index on the Domain column
  2. Create the new unique index with an explicit, stable name

This ensures older installations properly enforce the uniqueness constraint on upgrade.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@management/internals/modules/reverseproxy/service/service.go` at line 137,
Add a post-AutoMigrate migration in getMigrationsPostAuto() to drop the legacy
non-unique index on the Domain column and create a new unique index with a
stable name: locate the ReverseProxy service model field "Domain" and in
getMigrationsPostAuto() (management/server/store/store.go) run raw SQL (or use
GORM's Migrator) to DROP INDEX if exists for the old non-unique index name and
then CREATE UNIQUE INDEX <stable_name> ON <table>(Domain); ensure the migration
is idempotent (check existence before drop/create) so upgrades from older
installs remove the old index and enforce uniqueness.

ProxyCluster string `gorm:"index"`
Targets []*Target `gorm:"foreignKey:ServiceID;constraint:OnDelete:CASCADE"`
Enabled bool
Expand Down Expand Up @@ -535,15 +535,15 @@ var hopByHopHeaders = map[string]struct{}{
// reservedHeaders are set authoritatively by the proxy or control HTTP framing
// and cannot be overridden.
var reservedHeaders = map[string]struct{}{
"Content-Length": {},
"Content-Type": {},
"Cookie": {},
"Forwarded": {},
"X-Forwarded-For": {},
"X-Forwarded-Host": {},
"X-Forwarded-Port": {},
"X-Forwarded-Proto": {},
"X-Real-Ip": {},
"Content-Length": {},
"Content-Type": {},
"Cookie": {},
"Forwarded": {},
"X-Forwarded-For": {},
"X-Forwarded-Host": {},
"X-Forwarded-Port": {},
"X-Forwarded-Proto": {},
"X-Real-Ip": {},
}

func validateTargetOptions(idx int, opts *TargetOptions) error {
Expand Down
4 changes: 2 additions & 2 deletions management/server/store/sql_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -4977,9 +4977,9 @@ func (s *SqlStore) GetServiceByID(ctx context.Context, lockStrength LockingStren
return service, nil
}

func (s *SqlStore) GetServiceByDomain(ctx context.Context, accountID, domain string) (*rpservice.Service, error) {
func (s *SqlStore) GetServiceByDomain(ctx context.Context, domain string) (*rpservice.Service, error) {
var service *rpservice.Service
result := s.db.Preload("Targets").Where("account_id = ? AND domain = ?", accountID, domain).First(&service)
result := s.db.Preload("Targets").Where("domain = ?", domain).First(&service)
Comment thread
pascal-fischer marked this conversation as resolved.
if result.Error != nil {
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
return nil, status.Errorf(status.NotFound, "service with domain %s not found", domain)
Expand Down
2 changes: 1 addition & 1 deletion management/server/store/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ type Store interface {
UpdateService(ctx context.Context, service *rpservice.Service) error
DeleteService(ctx context.Context, accountID, serviceID string) error
GetServiceByID(ctx context.Context, lockStrength LockingStrength, accountID, serviceID string) (*rpservice.Service, error)
GetServiceByDomain(ctx context.Context, accountID, domain string) (*rpservice.Service, error)
GetServiceByDomain(ctx context.Context, domain string) (*rpservice.Service, error)
GetServices(ctx context.Context, lockStrength LockingStrength) ([]*rpservice.Service, error)
GetAccountServices(ctx context.Context, lockStrength LockingStrength, accountID string) ([]*rpservice.Service, error)

Expand Down
8 changes: 4 additions & 4 deletions management/server/store/store_mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading