f-28: add subnet default_route field
Signed-off-by: GnomeZworc <nicolas.boufidjeline@g3e.fr>
This commit is contained in:
parent
76a840b80a
commit
bb5698fdda
7 changed files with 99 additions and 38 deletions
|
|
@ -358,6 +358,12 @@ components:
|
||||||
type: string
|
type: string
|
||||||
description: Subnet CIDR block
|
description: Subnet CIDR block
|
||||||
example: "10.10.10.0/24"
|
example: "10.10.10.0/24"
|
||||||
|
default_route:
|
||||||
|
type: boolean
|
||||||
|
description: >
|
||||||
|
If true, advertise a default route via DHCP. For vxlan mode the gateway is the interface IP.
|
||||||
|
For bridge mode the gateway is read from the host routing table.
|
||||||
|
default: false
|
||||||
|
|
||||||
Subnet:
|
Subnet:
|
||||||
type: object
|
type: object
|
||||||
|
|
@ -390,6 +396,9 @@ components:
|
||||||
cidr:
|
cidr:
|
||||||
type: string
|
type: string
|
||||||
example: "10.10.10.0/24"
|
example: "10.10.10.0/24"
|
||||||
|
default_route:
|
||||||
|
type: boolean
|
||||||
|
example: false
|
||||||
|
|
||||||
VMCreateRequest:
|
VMCreateRequest:
|
||||||
type: object
|
type: object
|
||||||
|
|
|
||||||
|
|
@ -12,24 +12,26 @@ type VPC struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type SubnetCreateRequest struct {
|
type SubnetCreateRequest struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
VPC string `json:"vpc"`
|
VPC string `json:"vpc"`
|
||||||
Mode string `json:"mode"`
|
Mode string `json:"mode"`
|
||||||
VxlanID int `json:"vxlan_id"`
|
VxlanID int `json:"vxlan_id"`
|
||||||
IfaceType string `json:"iface_type"`
|
IfaceType string `json:"iface_type"`
|
||||||
InterfaceIP string `json:"interface_ip"`
|
InterfaceIP string `json:"interface_ip"`
|
||||||
CIDR string `json:"cidr"`
|
CIDR string `json:"cidr"`
|
||||||
|
DefaultRoute bool `json:"default_route"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Subnet struct {
|
type Subnet struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
State string `json:"state"`
|
State string `json:"state"`
|
||||||
VPC string `json:"vpc"`
|
VPC string `json:"vpc"`
|
||||||
Mode string `json:"mode"`
|
Mode string `json:"mode"`
|
||||||
VxlanID int `json:"vxlan_id"`
|
VxlanID int `json:"vxlan_id"`
|
||||||
LocalIface string `json:"local_iface"`
|
LocalIface string `json:"local_iface"`
|
||||||
InterfaceIP string `json:"interface_ip"`
|
InterfaceIP string `json:"interface_ip"`
|
||||||
CIDR string `json:"cidr"`
|
CIDR string `json:"cidr"`
|
||||||
|
DefaultRoute bool `json:"default_route"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type VMInterface struct {
|
type VMInterface struct {
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,8 @@ func (s *Server) getSubnet(w http.ResponseWriter, _ *http.Request, name string)
|
||||||
sub.InterfaceIP = value
|
sub.InterfaceIP = value
|
||||||
case "cidr":
|
case "cidr":
|
||||||
sub.CIDR = value
|
sub.CIDR = value
|
||||||
|
case "default_route":
|
||||||
|
sub.DefaultRoute = value == "true"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,8 @@ func (s *Server) listSubnets(w http.ResponseWriter, _ *http.Request) {
|
||||||
subnets[name].InterfaceIP = value
|
subnets[name].InterfaceIP = value
|
||||||
case "cidr":
|
case "cidr":
|
||||||
subnets[name].CIDR = value
|
subnets[name].CIDR = value
|
||||||
|
case "default_route":
|
||||||
|
subnets[name].DefaultRoute = value == "true"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result := make([]Subnet, 0, len(subnets))
|
result := make([]Subnet, 0, len(subnets))
|
||||||
|
|
@ -77,13 +79,14 @@ func (s *Server) postSubnet(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cmd := dispatcher.CreateSubnetCommand{
|
cmd := dispatcher.CreateSubnetCommand{
|
||||||
Name: req.Name,
|
Name: req.Name,
|
||||||
VPC: req.VPC,
|
VPC: req.VPC,
|
||||||
Mode: req.Mode,
|
Mode: req.Mode,
|
||||||
VxlanID: req.VxlanID,
|
VxlanID: req.VxlanID,
|
||||||
IfaceType: req.IfaceType,
|
IfaceType: req.IfaceType,
|
||||||
InterfaceIP: req.InterfaceIP,
|
InterfaceIP: req.InterfaceIP,
|
||||||
CIDR: req.CIDR,
|
CIDR: req.CIDR,
|
||||||
|
DefaultRoute: req.DefaultRoute,
|
||||||
}
|
}
|
||||||
if err := s.dispatcher.Prepare(cmd); err != nil {
|
if err := s.dispatcher.Prepare(cmd); err != nil {
|
||||||
if _, dbErr := kv.GetFromDB(s.db, "subnet/"+req.Name+"/state"); dbErr == nil {
|
if _, dbErr := kv.GetFromDB(s.db, "subnet/"+req.Name+"/state"); dbErr == nil {
|
||||||
|
|
@ -122,6 +125,8 @@ func (s *Server) postSubnet(w http.ResponseWriter, r *http.Request) {
|
||||||
sub.InterfaceIP = value
|
sub.InterfaceIP = value
|
||||||
case "cidr":
|
case "cidr":
|
||||||
sub.CIDR = value
|
sub.CIDR = value
|
||||||
|
case "default_route":
|
||||||
|
sub.DefaultRoute = value == "true"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
w.WriteHeader(http.StatusAccepted)
|
w.WriteHeader(http.StatusAccepted)
|
||||||
|
|
|
||||||
|
|
@ -12,13 +12,14 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type CreateSubnetCommand struct {
|
type CreateSubnetCommand struct {
|
||||||
Name string
|
Name string
|
||||||
VPC string
|
VPC string
|
||||||
Mode string
|
Mode string
|
||||||
VxlanID int
|
VxlanID int
|
||||||
IfaceType string
|
IfaceType string
|
||||||
InterfaceIP string
|
InterfaceIP string
|
||||||
CIDR string
|
CIDR string
|
||||||
|
DefaultRoute bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c CreateSubnetCommand) Prepare(db *badger.DB, cfg *configuration.Config) error {
|
func (c CreateSubnetCommand) Prepare(db *badger.DB, cfg *configuration.Config) error {
|
||||||
|
|
@ -48,6 +49,7 @@ func (c CreateSubnetCommand) Prepare(db *badger.DB, cfg *configuration.Config) e
|
||||||
kv.AddInDB(db, "subnet/"+c.Name+"/local_iface", localIface)
|
kv.AddInDB(db, "subnet/"+c.Name+"/local_iface", localIface)
|
||||||
kv.AddInDB(db, "subnet/"+c.Name+"/interface_ip", c.InterfaceIP)
|
kv.AddInDB(db, "subnet/"+c.Name+"/interface_ip", c.InterfaceIP)
|
||||||
kv.AddInDB(db, "subnet/"+c.Name+"/cidr", c.CIDR)
|
kv.AddInDB(db, "subnet/"+c.Name+"/cidr", c.CIDR)
|
||||||
|
kv.AddInDB(db, "subnet/"+c.Name+"/default_route", strconv.FormatBool(c.DefaultRoute))
|
||||||
if c.Mode == "vxlan" {
|
if c.Mode == "vxlan" {
|
||||||
kv.AddInDB(db, "subnet/"+c.Name+"/vxlan_id", strconv.Itoa(c.VxlanID))
|
kv.AddInDB(db, "subnet/"+c.Name+"/vxlan_id", strconv.Itoa(c.VxlanID))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -173,6 +173,40 @@ func TestCreateSubnetCommand_Prepare_UnknownMode(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCreateSubnetCommand_Prepare_DefaultRouteStored(t *testing.T) {
|
||||||
|
_, db := newTestDispatcher(t)
|
||||||
|
kv.AddInDB(db, "vpc/vpc-1/state", "created")
|
||||||
|
cmd := CreateSubnetCommand{
|
||||||
|
Name: "sn-1", VPC: "vpc-1", VxlanID: 100,
|
||||||
|
IfaceType: "vms", InterfaceIP: "10.0.0.1", CIDR: "10.0.0.0/24",
|
||||||
|
DefaultRoute: true,
|
||||||
|
}
|
||||||
|
if err := cmd.Prepare(db, testCfg()); err != nil {
|
||||||
|
t.Fatalf("Prepare a échoué : %v", err)
|
||||||
|
}
|
||||||
|
val, err := kv.GetFromDB(db, "subnet/sn-1/default_route")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("default_route non écrit en DB : %v", err)
|
||||||
|
}
|
||||||
|
if val != "true" {
|
||||||
|
t.Errorf("default_route attendu true, obtenu %q", val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCreateSubnetCommand_Prepare_DefaultRouteFalseByDefault(t *testing.T) {
|
||||||
|
_, db := newTestDispatcher(t)
|
||||||
|
kv.AddInDB(db, "vpc/vpc-1/state", "created")
|
||||||
|
cmd := CreateSubnetCommand{
|
||||||
|
Name: "sn-1", VPC: "vpc-1", VxlanID: 100,
|
||||||
|
IfaceType: "vms", InterfaceIP: "10.0.0.1", CIDR: "10.0.0.0/24",
|
||||||
|
}
|
||||||
|
cmd.Prepare(db, testCfg())
|
||||||
|
val, _ := kv.GetFromDB(db, "subnet/sn-1/default_route")
|
||||||
|
if val != "false" {
|
||||||
|
t.Errorf("default_route attendu false, obtenu %q", val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// --- DeleteSubnetCommand.Prepare ---
|
// --- DeleteSubnetCommand.Prepare ---
|
||||||
|
|
||||||
func TestDeleteSubnetCommand_Prepare_Success(t *testing.T) {
|
func TestDeleteSubnetCommand_Prepare_Success(t *testing.T) {
|
||||||
|
|
|
||||||
|
|
@ -11,15 +11,16 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type subnetData struct {
|
type subnetData struct {
|
||||||
vpc string
|
vpc string
|
||||||
subnetID string
|
subnetID string
|
||||||
bridge string
|
bridge string
|
||||||
mode string
|
mode string
|
||||||
vxlanID int
|
vxlanID int
|
||||||
localIface string
|
localIface string
|
||||||
interfaceIP net.IP
|
interfaceIP net.IP
|
||||||
cidr *net.IPNet
|
cidr *net.IPNet
|
||||||
vpcCIDR *net.IPNet
|
vpcCIDR *net.IPNet
|
||||||
|
defaultRoute bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadSubnet(db *badger.DB, name string) (subnetData, error) {
|
func loadSubnet(db *badger.DB, name string) (subnetData, error) {
|
||||||
|
|
@ -78,6 +79,12 @@ func loadSubnet(db *badger.DB, name string) (subnetData, error) {
|
||||||
}
|
}
|
||||||
d.cidr = ipNet
|
d.cidr = ipNet
|
||||||
|
|
||||||
|
defaultRouteStr, err := kv.GetFromDB(db, "subnet/"+name+"/default_route")
|
||||||
|
if err != nil {
|
||||||
|
return d, fmt.Errorf("get default_route: %w", err)
|
||||||
|
}
|
||||||
|
d.defaultRoute = defaultRouteStr == "true"
|
||||||
|
|
||||||
vpcCIDRStr, err := kv.GetFromDB(db, "vpc/"+d.vpc+"/cidr")
|
vpcCIDRStr, err := kv.GetFromDB(db, "vpc/"+d.vpc+"/cidr")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return d, fmt.Errorf("get vpc cidr: %w", err)
|
return d, fmt.Errorf("get vpc cidr: %w", err)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue