f-25: vms: add iptables gestion
Signed-off-by: GnomeZworc <nicolas.boufidjeline@g3e.fr>
This commit is contained in:
parent
a5bf748bdf
commit
504a2a723b
3 changed files with 89 additions and 12 deletions
42
internal/iptables/iptables.go
Normal file
42
internal/iptables/iptables.go
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
package iptables
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os/exec"
|
||||||
|
)
|
||||||
|
|
||||||
|
func addRule(args ...string) error {
|
||||||
|
return exec.Command("iptables", append([]string{"-t", "nat", "-A"}, args...)...).Run()
|
||||||
|
}
|
||||||
|
|
||||||
|
func deleteRule(args ...string) error {
|
||||||
|
return exec.Command("iptables", append([]string{"-t", "nat", "-D"}, args...)...).Run()
|
||||||
|
}
|
||||||
|
|
||||||
|
func AddMetadataRedirect(vmIP, gatewayIP, metadataPort string) error {
|
||||||
|
if err := addRule("PREROUTING",
|
||||||
|
"-s", vmIP+"/32",
|
||||||
|
"-d", "169.254.169.254/32",
|
||||||
|
"-p", "tcp", "-m", "tcp",
|
||||||
|
"--dport", "80",
|
||||||
|
"-j", "DNAT",
|
||||||
|
"--to-destination", gatewayIP+":"+metadataPort,
|
||||||
|
); err != nil {
|
||||||
|
return fmt.Errorf("iptables metadata redirect: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteMetadataRedirect(vmIP, gatewayIP, metadataPort string) error {
|
||||||
|
if err := deleteRule("PREROUTING",
|
||||||
|
"-s", vmIP+"/32",
|
||||||
|
"-d", "169.254.169.254/32",
|
||||||
|
"-p", "tcp", "-m", "tcp",
|
||||||
|
"--dport", "80",
|
||||||
|
"-j", "DNAT",
|
||||||
|
"--to-destination", gatewayIP+":"+metadataPort,
|
||||||
|
); err != nil {
|
||||||
|
return fmt.Errorf("iptables delete metadata redirect: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"git.g3e.fr/syonad/two/internal/iptables"
|
||||||
"git.g3e.fr/syonad/two/internal/metadata"
|
"git.g3e.fr/syonad/two/internal/metadata"
|
||||||
"git.g3e.fr/syonad/two/internal/netif"
|
"git.g3e.fr/syonad/two/internal/netif"
|
||||||
"git.g3e.fr/syonad/two/internal/netns"
|
"git.g3e.fr/syonad/two/internal/netns"
|
||||||
|
|
@ -41,6 +42,21 @@ func StartVM(db *badger.DB, name string) error {
|
||||||
return fmt.Errorf("parse tap_id: %w", err)
|
return fmt.Errorf("parse tap_id: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vmIP, err := kv.GetFromDB(db, "vm/"+name+"/ip")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("get ip: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
gatewayIP, err := kv.GetFromDB(db, "vm/"+name+"/gateway_ip")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("get gateway_ip: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
metadataPort, err := kv.GetFromDB(db, "vm/"+name+"/metadata_port")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("get metadata_port: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
mac, err := kv.GetFromDB(db, "vm/"+name+"/mac")
|
mac, err := kv.GetFromDB(db, "vm/"+name+"/mac")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("get mac: %w", err)
|
return fmt.Errorf("get mac: %w", err)
|
||||||
|
|
@ -63,16 +79,6 @@ func StartVM(db *badger.DB, name string) error {
|
||||||
}
|
}
|
||||||
cpus, _ := strconv.Atoi(cpusStr)
|
cpus, _ := strconv.Atoi(cpusStr)
|
||||||
|
|
||||||
bindIP, err := kv.GetFromDB(db, "vm/"+name+"/metadata_bind_ip")
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("get metadata_bind_ip: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
bindPort, err := kv.GetFromDB(db, "vm/"+name+"/metadata_bind_port")
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("get metadata_bind_port: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
password, _ := kv.GetFromDB(db, "vm/"+name+"/password")
|
password, _ := kv.GetFromDB(db, "vm/"+name+"/password")
|
||||||
sshkey, _ := kv.GetFromDB(db, "vm/"+name+"/sshkey")
|
sshkey, _ := kv.GetFromDB(db, "vm/"+name+"/sshkey")
|
||||||
|
|
||||||
|
|
@ -80,11 +86,17 @@ func StartVM(db *badger.DB, name string) error {
|
||||||
return fmt.Errorf("create tap: %w", err)
|
return fmt.Errorf("create tap: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := netns.Call(vpcName, func() error {
|
||||||
|
return iptables.AddMetadataRedirect(vmIP, gatewayIP, metadataPort)
|
||||||
|
}); err != nil {
|
||||||
|
return fmt.Errorf("add metadata redirect: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
if err := metadata.StartMetadata(metadata.NoCloudConfig{
|
if err := metadata.StartMetadata(metadata.NoCloudConfig{
|
||||||
Name: name,
|
Name: name,
|
||||||
VpcName: vpcName,
|
VpcName: vpcName,
|
||||||
BindIP: bindIP,
|
BindIP: gatewayIP,
|
||||||
BindPort: bindPort,
|
BindPort: metadataPort,
|
||||||
Password: password,
|
Password: password,
|
||||||
SSHKEY: sshkey,
|
SSHKEY: sshkey,
|
||||||
}, db, false); err != nil {
|
}, db, false); err != nil {
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,10 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
configuration "git.g3e.fr/syonad/two/internal/config/agent"
|
configuration "git.g3e.fr/syonad/two/internal/config/agent"
|
||||||
|
"git.g3e.fr/syonad/two/internal/iptables"
|
||||||
"git.g3e.fr/syonad/two/internal/metadata"
|
"git.g3e.fr/syonad/two/internal/metadata"
|
||||||
"git.g3e.fr/syonad/two/internal/netif"
|
"git.g3e.fr/syonad/two/internal/netif"
|
||||||
|
"git.g3e.fr/syonad/two/internal/netns"
|
||||||
"git.g3e.fr/syonad/two/internal/qmp"
|
"git.g3e.fr/syonad/two/internal/qmp"
|
||||||
"git.g3e.fr/syonad/two/pkg/db/kv"
|
"git.g3e.fr/syonad/two/pkg/db/kv"
|
||||||
|
|
||||||
|
|
@ -37,6 +39,21 @@ func StopVM(db *badger.DB, name string, cfg *configuration.Config) error {
|
||||||
return fmt.Errorf("parse tap_id: %w", err)
|
return fmt.Errorf("parse tap_id: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vmIP, err := kv.GetFromDB(db, "vm/"+name+"/ip")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("get ip: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
gatewayIP, err := kv.GetFromDB(db, "vm/"+name+"/gateway_ip")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("get gateway_ip: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
metadataPort, err := kv.GetFromDB(db, "vm/"+name+"/metadata_port")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("get metadata_port: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
socketPath := fmt.Sprintf("/tmp/%s.qmp-sock", name)
|
socketPath := fmt.Sprintf("/tmp/%s.qmp-sock", name)
|
||||||
|
|
||||||
if _, err := qmp.Send(socketPath, []string{`{"execute":"system_powerdown"}`}); err != nil {
|
if _, err := qmp.Send(socketPath, []string{`{"execute":"system_powerdown"}`}); err != nil {
|
||||||
|
|
@ -59,6 +76,12 @@ func StopVM(db *badger.DB, name string, cfg *configuration.Config) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := netns.Call(vpcName, func() error {
|
||||||
|
return iptables.DeleteMetadataRedirect(vmIP, gatewayIP, metadataPort)
|
||||||
|
}); err != nil {
|
||||||
|
return fmt.Errorf("delete metadata redirect: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
if err := metadata.StopMetadata(name, db, false); err != nil {
|
if err := metadata.StopMetadata(name, db, false); err != nil {
|
||||||
return fmt.Errorf("stop metadata: %w", err)
|
return fmt.Errorf("stop metadata: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue