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

Migrate ipam to use the grpc service #522

Merged
merged 40 commits into from
Jul 3, 2024
Merged
Show file tree
Hide file tree
Changes from 37 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
9161f3e
Migrate ipam to use the grpc service
majst01 Apr 30, 2024
843524a
Fix integration test
majst01 May 1, 2024
f9ef2a5
Remove useless nil checks
majst01 May 3, 2024
6a7c274
Merge master
majst01 May 7, 2024
f50838f
Merge branch 'master' into ipam-as-service
majst01 May 8, 2024
f27b62c
Merge master
majst01 May 30, 2024
19c4667
Merge branch 'ipam-as-service' of https://github.com/metal-stack/meta…
majst01 May 30, 2024
e210dc7
Tidy
majst01 May 30, 2024
e6c56f2
Tidy
majst01 May 30, 2024
3dece7e
Remove unneeded func
majst01 May 30, 2024
6f7d961
Merge branch 'master' into ipam-as-service
Gerrit91 Jun 3, 2024
2b74dda
Check ipam service on startup
majst01 Jun 3, 2024
ac52f45
Version fix
majst01 Jun 4, 2024
03df0fa
Update actions
majst01 Jun 4, 2024
292005d
Merge branch 'master' of https://github.com/metal-stack/metal-api int…
majst01 Jun 4, 2024
207cfec
Updates
majst01 Jun 4, 2024
301ac24
Add ipam to health status
majst01 Jun 4, 2024
ded94b4
Merge branch 'master' of https://github.com/metal-stack/metal-api int…
majst01 Jun 11, 2024
834bd81
Merge master
majst01 Jun 11, 2024
7694a58
Pin go-ipam
majst01 Jun 11, 2024
a19cc00
Update protobuf
majst01 Jun 12, 2024
b7d7a2c
merge master
majst01 Jun 12, 2024
aafab8c
Remove duplicate checks
majst01 Jun 14, 2024
2dfd650
updates
majst01 Jun 18, 2024
d3c00bb
Finally return conflict if desired
majst01 Jun 18, 2024
05539fc
Unexport
majst01 Jun 18, 2024
328f740
Smallish
majst01 Jun 18, 2024
ca16667
Proper returncodes for alreadyexist and notfound ips
majst01 Jun 20, 2024
30e144a
Handle error in search term
majst01 Jun 24, 2024
e51c045
Fix network search
majst01 Jun 24, 2024
1fbb584
Less verbose logging during tests
majst01 Jul 1, 2024
ce51743
Remove silly test
majst01 Jul 1, 2024
c4b3731
Satisfy linter
majst01 Jul 1, 2024
6b76ec2
Even less logging during tests
majst01 Jul 1, 2024
31a474b
Better description
majst01 Jul 2, 2024
021ee86
Merge master
majst01 Jul 2, 2024
f272584
Remove rootcmds, add networkquery validation
majst01 Jul 2, 2024
038d964
Useful default
majst01 Jul 2, 2024
a8b3a46
Use revision for health report of ipam
majst01 Jul 2, 2024
b83778f
Merge branch 'master' into ipam-as-service
majst01 Jul 2, 2024
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
2 changes: 1 addition & 1 deletion .github/workflows/docker.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:
cache: false

- name: Lint
uses: golangci/golangci-lint-action@v4
uses: golangci/golangci-lint-action@v6
with:
args: --build-tags integration -p bugs -p unused -D protogetter --timeout=5m

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release-drafter.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: release-drafter/release-drafter@v5
- uses: release-drafter/release-drafter@v6
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
14 changes: 9 additions & 5 deletions cmd/metal-api/internal/datastore/integer_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ package datastore
import (
"context"
"log/slog"
"os"
"sync"
"time"

"github.com/metal-stack/metal-api/cmd/metal-api/internal/metal"
"github.com/metal-stack/metal-api/test"
Expand All @@ -25,7 +25,9 @@ func TestRethinkStore_AcquireRandomUniqueIntegerIntegration(t *testing.T) {
_ = container.Terminate(context.Background())
}()

rs := New(slog.Default(), c.IP+":"+c.Port, c.DB, c.User, c.Password)
log := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelError}))

rs := New(log, c.IP+":"+c.Port, c.DB, c.User, c.Password)
rs.VRFPoolRangeMin = 10000
rs.VRFPoolRangeMax = 10010
rs.ASNPoolRangeMin = 10000
Expand All @@ -49,8 +51,9 @@ func TestRethinkStore_AcquireUniqueIntegerTwiceIntegration(t *testing.T) {
defer func() {
_ = container.Terminate(context.Background())
}()
log := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelError}))

rs := New(slog.Default(), c.IP+":"+c.Port, c.DB, c.User, c.Password)
rs := New(log, c.IP+":"+c.Port, c.DB, c.User, c.Password)
rs.VRFPoolRangeMin = 10000
rs.VRFPoolRangeMax = 10010
rs.ASNPoolRangeMin = 10000
Expand All @@ -77,7 +80,9 @@ func TestRethinkStore_AcquireUniqueIntegerPoolExhaustionIntegration(t *testing.T
_ = container.Terminate(context.Background())
}()

rs := New(slog.Default(), c.IP+":"+c.Port, c.DB, c.User, c.Password)
log := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelError}))

rs := New(log, c.IP+":"+c.Port, c.DB, c.User, c.Password)
rs.VRFPoolRangeMin = 10000
rs.VRFPoolRangeMax = 10010
rs.ASNPoolRangeMin = 10000
Expand All @@ -101,7 +106,6 @@ func TestRethinkStore_AcquireUniqueIntegerPoolExhaustionIntegration(t *testing.T
}
assert.GreaterOrEqual(t, got, uint(rs.VRFPoolRangeMin))
assert.LessOrEqual(t, got, uint(rs.VRFPoolRangeMax))
t.Logf("acquired a vrf %d at: %s", got, time.Now())
}()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package datastore
import (
"context"
"log/slog"
"os"
"strconv"
"strings"
"sync"
Expand Down Expand Up @@ -947,7 +948,7 @@ func TestRethinkStore_UpdateMachine(t *testing.T) {
func Test_FindWaitingMachine_NoConcurrentModificationErrors(t *testing.T) {

var (
root = slog.Default()
root = slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelError}))
wg sync.WaitGroup
size = metal.Size{Base: metal.Base{ID: "1"}}
count int
Expand Down Expand Up @@ -1023,7 +1024,7 @@ func Test_FindWaitingMachine_NoConcurrentModificationErrors(t *testing.T) {
continue
}

log.Info("waiting machine found")
log.Debug("waiting machine found")

newMachine := *machine
newMachine.PreAllocated = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package migrations_integration
import (
"context"
"log/slog"
"os"
"time"

"github.com/google/go-cmp/cmp"
Expand All @@ -28,7 +29,9 @@ func Test_Migration(t *testing.T) {
_ = container.Terminate(context.Background())
}()

rs := datastore.New(slog.Default(), c.IP+":"+c.Port, c.DB, c.User, c.Password)
log := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelError}))

rs := datastore.New(log, c.IP+":"+c.Port, c.DB, c.User, c.Password)
rs.VRFPoolRangeMin = 10000
rs.VRFPoolRangeMax = 10010
rs.ASNPoolRangeMin = 10000
Expand Down
82 changes: 59 additions & 23 deletions cmd/metal-api/internal/datastore/network.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package datastore

import (
"errors"
"fmt"
"net/netip"
"strconv"

"github.com/metal-stack/metal-api/cmd/metal-api/internal/metal"
"github.com/metal-stack/metal-api/cmd/metal-api/internal/utils"
r "gopkg.in/rethinkdb/rethinkdb-go.v6"
)

Expand All @@ -24,8 +26,28 @@ type NetworkSearchQuery struct {
Labels map[string]string `json:"labels" optional:"true"`
}

func (p *NetworkSearchQuery) Validate() error {
var errs []error
for _, prefix := range p.Prefixes {
_, err := netip.ParsePrefix(prefix)
if err != nil {
errs = append(errs, err)
}
}
for _, prefix := range p.DestinationPrefixes {
_, err := netip.ParsePrefix(prefix)
if err != nil {
errs = append(errs, err)
}
}
if len(errs) == 0 {
return nil
}
return errors.Join(errs...)
}

// GenerateTerm generates the project search query term.
func (p *NetworkSearchQuery) generateTerm(rs *RethinkStore) *r.Term {
func (p *NetworkSearchQuery) generateTerm(rs *RethinkStore) (*r.Term, error) {
q := *rs.networkTable()

if p.ID != nil {
Expand Down Expand Up @@ -91,42 +113,48 @@ func (p *NetworkSearchQuery) generateTerm(rs *RethinkStore) *r.Term {
}

for _, prefix := range p.Prefixes {
ip, length := utils.SplitCIDR(prefix)
pfx, err := netip.ParsePrefix(prefix)
if err != nil {
return nil, fmt.Errorf("unable to parse prefix %w", err)
Gerrit91 marked this conversation as resolved.
Show resolved Hide resolved
}
ip := pfx.Addr()
length := pfx.Bits()

q = q.Filter(func(row r.Term) r.Term {
return row.Field("prefixes").Map(func(p r.Term) r.Term {
return p.Field("ip")
}).Contains(r.Expr(ip))
}).Contains(r.Expr(ip.String()))
Gerrit91 marked this conversation as resolved.
Show resolved Hide resolved
})

if length != nil {
q = q.Filter(func(row r.Term) r.Term {
return row.Field("prefixes").Map(func(p r.Term) r.Term {
return p.Field("length")
}).Contains(r.Expr(strconv.Itoa(*length)))
})
}
q = q.Filter(func(row r.Term) r.Term {
return row.Field("prefixes").Map(func(p r.Term) r.Term {
return p.Field("length")
}).Contains(r.Expr(strconv.Itoa(length)))
})
}

for _, destPrefix := range p.DestinationPrefixes {
ip, length := utils.SplitCIDR(destPrefix)
pfx, err := netip.ParsePrefix(destPrefix)
if err != nil {
return nil, fmt.Errorf("unable to parse prefix %w", err)
}
ip := pfx.Addr()
length := pfx.Bits()

q = q.Filter(func(row r.Term) r.Term {
return row.Field("destinationprefixes").Map(func(dp r.Term) r.Term {
return dp.Field("ip")
}).Contains(r.Expr(ip))
}).Contains(r.Expr(ip.String()))
})

if length != nil {
q = q.Filter(func(row r.Term) r.Term {
return row.Field("destinationprefixes").Map(func(dp r.Term) r.Term {
return dp.Field("length")
}).Contains(r.Expr(strconv.Itoa(*length)))
})
}
q = q.Filter(func(row r.Term) r.Term {
return row.Field("destinationprefixes").Map(func(dp r.Term) r.Term {
return dp.Field("length")
}).Contains(r.Expr(strconv.Itoa(length)))
})
}

return &q
return &q, nil
}

// FindNetworkByID returns an network of a given id.
Expand All @@ -141,12 +169,20 @@ func (rs *RethinkStore) FindNetworkByID(id string) (*metal.Network, error) {

// FindNetwork returns a machine by the given query, fails if there is no record or multiple records found.
func (rs *RethinkStore) FindNetwork(q *NetworkSearchQuery, n *metal.Network) error {
return rs.findEntity(q.generateTerm(rs), &n)
term, err := q.generateTerm(rs)
if err != nil {
return err
}
return rs.findEntity(term, &n)
}

// SearchNetworks returns the networks that match the given properties
func (rs *RethinkStore) SearchNetworks(q *NetworkSearchQuery, ns *metal.Networks) error {
return rs.searchEntities(q.generateTerm(rs), ns)
term, err := q.generateTerm(rs)
if err != nil {
return err
}
return rs.searchEntities(term, ns)
}

// ListNetworks returns all networks.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func startRethinkInitialized() (container testcontainers.Container, ds *RethinkS
panic(err)
}

rs := New(slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelDebug})), c.IP+":"+c.Port, c.DB, c.User, c.Password)
rs := New(slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelError})), c.IP+":"+c.Port, c.DB, c.User, c.Password)

rs.VRFPoolRangeMin = 10000
rs.VRFPoolRangeMax = 10010
Expand Down
3 changes: 2 additions & 1 deletion cmd/metal-api/internal/datastore/rethinkdb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package datastore

import (
"log/slog"
"os"
"testing"

"github.com/google/go-cmp/cmp"
Expand All @@ -11,7 +12,7 @@ import (
)

func TestNew(t *testing.T) {
logger := slog.Default()
logger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelError}))
type args struct {
log *slog.Logger
dbhost string
Expand Down
3 changes: 2 additions & 1 deletion cmd/metal-api/internal/datastore/testing.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package datastore

import (
"log/slog"
"os"
"testing"

r "gopkg.in/rethinkdb/rethinkdb-go.v6"
Expand All @@ -20,7 +21,7 @@ Return Values:
*/
func InitMockDB(t *testing.T) (*RethinkStore, *r.Mock) {
rs := New(
slog.Default(),
slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelError})),
"db-addr",
"mockdb",
"db-user",
Expand Down
3 changes: 2 additions & 1 deletion cmd/metal-api/internal/eventbus/nsq_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package eventbus

import (
"log/slog"
"os"
"testing"

"github.com/metal-stack/metal-api/cmd/metal-api/internal/metal"
Expand All @@ -15,7 +16,7 @@ func TestNewNSQ(t *testing.T) {
HTTPEndpoint: "rest",
}
publisher := bus.NewPublisher
logger := slog.Default()
logger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelError}))
actual := NewNSQ(cfg, logger, publisher)

assert.NotNil(t, actual)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"io"
"log/slog"
"math/rand/v2"
"os"
"strconv"
"sync"
"testing"
Expand Down Expand Up @@ -220,7 +221,7 @@ func (t *test) startApiInstances(ds *datastore.RethinkStore) {
cfg := &ServerConfig{
Context: ctx,
Store: ds,
Logger: slog.Default(),
Logger: slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelError})),
GrpcPort: 50005 + i,
TlsEnabled: false,
ResponseInterval: 2 * time.Millisecond,
Expand Down
9 changes: 7 additions & 2 deletions cmd/metal-api/internal/grpc/boot-service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package grpc
import (
"context"
"log/slog"
"os"
"reflect"
"sync"
"testing"
Expand Down Expand Up @@ -33,6 +34,8 @@ func (p *emptyPublisher) CreateTopic(topic string) error {

func (p *emptyPublisher) Stop() {}
func TestBootService_Register(t *testing.T) {
log := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelError}))

tests := []struct {
name string
uuid string
Expand Down Expand Up @@ -162,7 +165,7 @@ func TestBootService_Register(t *testing.T) {
}

bootService := &BootService{
log: slog.Default(),
log: log,
ds: ds,
ipmiSuperUser: metal.DisabledIPMISuperUser(),
publisher: &emptyPublisher{},
Expand Down Expand Up @@ -193,6 +196,8 @@ func TestBootService_Register(t *testing.T) {
}

func TestBootService_Report(t *testing.T) {
log := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelError}))

tests := []struct {
name string
req *v1.BootServiceReportRequest
Expand Down Expand Up @@ -228,7 +233,7 @@ func TestBootService_Report(t *testing.T) {
tt := tt
t.Run(tt.name, func(t *testing.T) {
b := &BootService{
log: slog.Default(),
log: log,
ds: ds,
ipmiSuperUser: metal.DisabledIPMISuperUser(),
publisher: &emptyPublisher{},
Expand Down
4 changes: 3 additions & 1 deletion cmd/metal-api/internal/grpc/event-service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package grpc
import (
"context"
"log/slog"
"os"
"reflect"
"testing"

Expand All @@ -16,6 +17,7 @@ import (
func TestEventService_Send(t *testing.T) {
ds, mock := datastore.InitMockDB(t)
testdata.InitMockDBData(mock)
log := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelError}))

tests := []struct {
name string
Expand All @@ -36,7 +38,7 @@ func TestEventService_Send(t *testing.T) {
},
},
ds: ds,
log: slog.Default(),
log: log,
want: &v1.EventServiceSendResponse{
Events: uint64(1),
Failed: []string{},
Expand Down
Loading