diff --git a/cmd/metal-api/internal/datastore/ip.go b/cmd/metal-api/internal/datastore/ip.go index 5c54649a3..758dd68dc 100644 --- a/cmd/metal-api/internal/datastore/ip.go +++ b/cmd/metal-api/internal/datastore/ip.go @@ -97,6 +97,22 @@ func (rs *RethinkStore) SearchIPs(q *IPSearchQuery, ips *metal.IPs) error { return rs.searchEntities(q.generateTerm(rs), ips) } +// FindIPsByProjects returns all ips of given projects. +// FIXME no test present to check if the query actually works +// according to https://stackoverflow.com/questions/44424377/rethinkdb-query-filter-against-multiple-values-for-single-key it should :-) +func (rs *RethinkStore) FindIPsByProjects(projects []string) (metal.IPs, error) { + q := *rs.ipTable() + q = q.Filter(func(row r.Term) r.Term { + return row.Field("projectid").Contains(func(nw r.Term) r.Term { + return nw.Field("projectid").Contains(r.Expr(projects)) + }) + }) + + ips := make([]metal.IP, 0) + err := rs.searchEntities(&q, ips) + return ips, err +} + // ListIPs returns all ips. func (rs *RethinkStore) ListIPs() (metal.IPs, error) { ips := make([]metal.IP, 0) diff --git a/cmd/metal-api/internal/service/switch-service.go b/cmd/metal-api/internal/service/switch-service.go index 8fea0f965..8c7ba6fef 100644 --- a/cmd/metal-api/internal/service/switch-service.go +++ b/cmd/metal-api/internal/service/switch-service.go @@ -997,9 +997,12 @@ func makeSwitchCons(s *metal.Switch) []v1.SwitchConnection { } func findSwitchReferencedEntities(s *metal.Switch, ds *datastore.RethinkStore) (*metal.Partition, metal.IPsMap, metal.Machines, *metal.SwitchStatus, error) { - var err error - var p *metal.Partition - var m metal.Machines + var ( + err error + p *metal.Partition + ms metal.Machines + projects []string + ) if s.PartitionID != "" { p, err = ds.FindPartition(s.PartitionID) @@ -1007,13 +1010,17 @@ func findSwitchReferencedEntities(s *metal.Switch, ds *datastore.RethinkStore) ( return nil, nil, nil, nil, fmt.Errorf("switch %q references partition, but partition %q cannot be found in database: %w", s.ID, s.PartitionID, err) } - err = ds.SearchMachines(&datastore.MachineSearchQuery{PartitionID: &s.PartitionID}, &m) + err = ds.SearchMachines(&datastore.MachineSearchQuery{PartitionID: &s.PartitionID}, &ms) if err != nil { return nil, nil, nil, nil, fmt.Errorf("could not search machines of partition %q for switch %q: %w", s.PartitionID, s.ID, err) } } - ips, err := ds.ListIPs() + for project := range ms.ByProjectID() { + projects = append(projects, project) + } + + ips, err := ds.FindIPsByProjects(projects) if err != nil { return nil, nil, nil, nil, fmt.Errorf("ips could not be listed: %w", err) } @@ -1023,7 +1030,7 @@ func findSwitchReferencedEntities(s *metal.Switch, ds *datastore.RethinkStore) ( return nil, nil, nil, nil, fmt.Errorf("switchStatus could not be listed: %w", err) } - return p, ips.ByProjectID(), m, ss, nil + return p, ips.ByProjectID(), ms, ss, nil } func makeSwitchResponseList(ss metal.Switches, ds *datastore.RethinkStore) ([]*v1.SwitchResponse, error) {