diff --git a/agent/Home.md b/agent/Home.md index bbf9e7a..86b74b9 100644 --- a/agent/Home.md +++ b/agent/Home.md @@ -30,4 +30,5 @@ Tout cela serait lancer depuis une api: - [Reseaux](./agent/network/Home.md) - [Les vms](./agent/instance/Home.md) - [Serveur http](./agent/http/Home.md) -- [Persistance](./agent/persistance/Home.md) \ No newline at end of file +- [Persistance](./agent/persistance/Home.md) +- [Metadata](./agent/metadata/Home.md) \ No newline at end of file diff --git a/agent/metadata/Home.md b/agent/metadata/Home.md new file mode 100644 index 0000000..d362bfd --- /dev/null +++ b/agent/metadata/Home.md @@ -0,0 +1,120 @@ +# Metadata server + +```go +package metadata + +import ( + "fmt" + "net" + "net/http" + "strings" + "sync" +) + +type Metadata struct { + Name string + SSHKeys []string +} + +type Server struct { + metadata Metadata + listener net.Listener + server *http.Server + mu sync.Mutex + port int +} + +func New(metadata Metadata, port int) *Server { + return &Server{ + metadata: metadata, + port: port, + } +} + +func (s *Server) Start() error { + s.mu.Lock() + defer s.mu.Unlock() + + addr := fmt.Sprintf("127.0.0.1:%d", s.port) + ln, err := net.Listen("tcp", addr) + if err != nil { + return err + } + s.listener = ln + + mux := http.NewServeMux() + mux.HandleFunc("/meta-data", s.handleMetaData) + mux.HandleFunc("/user-data", s.handleUserData) + + s.server = &http.Server{ + Handler: mux, + } + go s.server.Serve(ln) + + return nil +} + +func (s *Server) Stop() error { + s.mu.Lock() + defer s.mu.Unlock() + + if s.server != nil { + return s.server.Close() + } + return nil +} + +func (s *Server) handleMetaData(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, "instance-id: %s\n", s.metadata.Name) + fmt.Fprintf(w, "local-hostname: %s\n", s.metadata.Name) +} + +func (s *Server) handleUserData(w http.ResponseWriter, r *http.Request) { + keys := strings.Join(s.metadata.SSHKeys, "\n - ") + userData := fmt.Sprintf(`#cloud-config +ssh_authorized_keys: + - %s +`, keys) + fmt.Fprint(w, userData) +} +``` + +```go +type VM struct { + Name string + SSHKeys []string + MetaServer *metadata.Server + MetaPort int + // ... autres champs comme PID, TAP name, etc. +} + +func StartVM(vm *VM) error { + meta := metadata.Metadata{ + Name: vm.Name, + SSHKeys: vm.SSHKeys, + } + metaSrv := metadata.New(meta, vm.MetaPort) + err := metaSrv.Start() + if err != nil { + return fmt.Errorf("metadata start failed: %w", err) + } + vm.MetaServer = metaSrv + + // suite du démarrage de la VM : QEMU, netns, redirection iptables... + + return nil +} + + +func StopVM(vm *VM) error { + // arrêter QEMU, nettoyer TAP, etc... + + if vm.MetaServer != nil { + err := vm.MetaServer.Stop() + if err != nil { + fmt.Printf("Erreur arrêt metadata VM %s: %v\n", vm.Name, err) + } + } + return nil +} +``` \ No newline at end of file