Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Only fetch required ips per switch describe instead of all #563

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
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
14 changes: 14 additions & 0 deletions cmd/metal-api/internal/datastore/ip.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,20 @@ 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(r.Expr(projects))
})

var ips metal.IPs
err := rs.searchEntities(&q, &ips)
return ips, err
}

// ListIPs returns all ips.
func (rs *RethinkStore) ListIPs() (metal.IPs, error) {
ips := make([]metal.IP, 0)
Expand Down
19 changes: 13 additions & 6 deletions cmd/metal-api/internal/service/switch-service.go
Original file line number Diff line number Diff line change
Expand Up @@ -997,23 +997,30 @@ 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)
if err != nil {
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)
}
Expand All @@ -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) {
Expand Down
5 changes: 5 additions & 0 deletions cmd/metal-api/internal/testdata/testdata.go
Original file line number Diff line number Diff line change
Expand Up @@ -891,6 +891,11 @@ func InitMockDBData(mock *r.Mock) {
mock.On(r.DB("mockdb").Table("image")).Return(TestImages, nil)
mock.On(r.DB("mockdb").Table("network")).Return(TestNetworks, nil)
mock.On(r.DB("mockdb").Table("ip")).Return(TestIPs, nil)

// FIXME still broken
// mock.On(r.DB("mockdb").Table("ip").Filter(func(var_273 r.Term) r.Term { return var_273.Field("projectid").Contains([]string{"p1", "p2"}) })).Return(nil, nil)
// mock.On(r.DB("mockdb").Table("ip").Filter(func(var_409 r.Term) r.Term { return var_409.Field("projectid").Contains([]string{}) })).Return(nil, nil)

mock.On(r.DB("mockdb").Table("machine")).Return(TestMachines, nil)
mock.On(r.DB("mockdb").Table("switch")).Return(TestSwitches, nil)
mock.On(r.DB("mockdb").Table("switchstatus")).Return(TestSwitchStates, nil)
Expand Down
Loading