Skip to content

Commit

Permalink
Add public IPs validation task
Browse files Browse the repository at this point in the history
  • Loading branch information
AbdelrahmanElawady committed Oct 17, 2023
1 parent 1d41a6f commit b8d3598
Showing 1 changed file with 109 additions and 0 deletions.
109 changes: 109 additions & 0 deletions pkg/perf/pubip_task.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package perf

import (
"context"
"fmt"
"io"
"net"
"net/http"
"strings"

"github.com/containernetworking/plugins/pkg/ns"
"github.com/threefoldtech/zos/pkg/environment"
"github.com/threefoldtech/zos/pkg/network/macvlan"
"github.com/threefoldtech/zos/pkg/network/namespace"
"github.com/threefoldtech/zos/pkg/network/types"
"github.com/vishvananda/netlink"
)

const macvlanName = "pubtestmacvlan"
const namespaceName = "pubtestns"

type PubIPTask struct {
taskID string
schedule string
}

var _ Task = (*PubIPTask)(nil)

func (p *PubIPTask) ID() string {
return p.taskID
}

func (p *PubIPTask) Cron() string {
return p.schedule
}

func (p *PubIPTask) Run(ctx context.Context) (interface{}, error) {
netNS, err := namespace.GetByName(namespaceName)
if err != nil {
netNS, err = namespace.Create(namespaceName)
if err != nil {
return nil, fmt.Errorf("failed to create namespace %s: %w", namespaceName, err)
}
}
mv, err := macvlan.GetByName(macvlanName)
if err != nil {
mv, err = macvlan.Create(macvlanName, types.PublicBridge, netNS)
if err != nil {
return nil, fmt.Errorf("failed to create macvlan %s: %w", namespaceName, err)
}
}
manager, err := environment.GetSubstrate()
if err != nil {
return nil, fmt.Errorf("failed to get substrate client: %w", err)
}
sub, err := manager.Substrate()
if err != nil {
return nil, fmt.Errorf("failed to get substrate client: %w", err)
}
farmID := environment.MustGet().FarmID
farm, err := sub.GetFarm(uint32(farmID))
if farm != nil {
return nil, fmt.Errorf("failed to get farm with id %d: %w", farmID, err)
}
unusedIPs := map[string]bool{}
for _, publicIP := range farm.PublicIPs {
if publicIP.ContractID == 0 {
unusedIPs[publicIP.IP] = false
}
}
for ip := range unusedIPs {
_, ipNet, err := net.ParseCIDR(ip)
if err != nil {
continue
}
err = macvlan.Install(mv, nil, []*net.IPNet{ipNet}, nil, netNS)
if err != nil {
return nil, fmt.Errorf("failed to install macvlan %s with ip %s to namespace %s: %w", macvlanName, ipNet, namespaceName, err)
}
err = netNS.Do(func(_ ns.NetNS) error {
req, err := http.Get("https://api.ipify.org/")
if err != nil {
return err
}

body, err := io.ReadAll(req.Body)
if err != nil {
req.Body.Close()
return err
}
req.Body.Close()

if ip == strings.TrimSpace(string(body)) {
unusedIPs[ip] = true
}
return nil
})
if err != nil {
return nil, fmt.Errorf("failed to check if ip is valid: %w", err)
}

}
err = netlink.LinkSetDown(mv)
if err != nil {
return nil, fmt.Errorf("failed to set macvlan %s link down: %w", macvlanName, err)
}

return unusedIPs, nil
}

0 comments on commit b8d3598

Please sign in to comment.