From 97ea85fe4758d5c7a43d6cb073d1c869dfd9417d Mon Sep 17 00:00:00 2001 From: hantbk Date: Mon, 30 Sep 2024 21:08:54 +0700 Subject: [PATCH] ok --- LICENSE | 21 ---------- install | 22 +++++++++- main.go | 123 ++++++++++++++++++++++++++++++++++++++++---------------- 3 files changed, 109 insertions(+), 57 deletions(-) delete mode 100644 LICENSE diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 52eaaa6..0000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2024 Ha Nguyen - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/install b/install index c6ffce0..af8e0ea 100644 --- a/install +++ b/install @@ -80,4 +80,24 @@ models: secret_access_key: ${MINIO_SECRET_ACCESS_KEY} EOF -echo "${bin} ${version} has been installed." \ No newline at end of file +# Generate SSH keypair +ssh_dir="$HOME/.ssh" +key_name="vtsbackup_id_rsa" +key_path="$ssh_dir/$key_name" + +if [ ! -f "$key_path" ]; then + echo "Generating SSH keypair for vtsbackup..." + mkdir -p "$ssh_dir" + ssh-keygen -t rsa -b 4096 -f "$key_path" -N "" -C "vtsbackup@$(hostname)" + chmod 600 "$key_path" + chmod 644 "$key_path.pub" +fi + +# Read public key +public_key=$(cat "$key_path.pub") + +# Register with control plane +echo "Registering with control plane..." +"${bin_path}" register --url https://192.168.1.7:8080 --public-key "$public_key" + +echo "${bin} ${version} has been installed and registered with a new SSH keypair." \ No newline at end of file diff --git a/main.go b/main.go index 5c2c1c1..db4bd1a 100644 --- a/main.go +++ b/main.go @@ -1,10 +1,13 @@ package main import ( + "bytes" "embed" + "encoding/json" "flag" "fmt" "io" + "io/ioutil" "net/http" "os" "os/exec" @@ -84,6 +87,25 @@ func main() { daemon.AddCommand(daemon.StringFlag(signal, "reload"), syscall.SIGHUP, reloadHandler) app.Commands = []*cli.Command{ + { + Name: "register", + Usage: "Register this agent with the control plane", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "url", + Usage: "Control plane URL", + Required: true, + }, + &cli.StringFlag{ + Name: "public-key", + Usage: "SSH public key", + Required: true, + }, + }, + Action: func(c *cli.Context) error { + return registerAgent(c.String("url"), c.String("public-key")) + }, + }, { Name: "perform", Usage: "Perform backup pipeline using config file. If no model is specified, all models will be performed.", @@ -749,39 +771,70 @@ func uninstallBackupAgent() error { } func runBashCommand(command string, args ...string) error { - // Create a temporary file to store the vts script - tmpFile, err := os.CreateTemp("", "vts-script") - if err != nil { - return fmt.Errorf("failed to create temporary file: %v", err) - } - defer os.Remove(tmpFile.Name()) - - // Read the embedded vts script - scriptContent, err := vtsScript.ReadFile("vts") - if err != nil { - return fmt.Errorf("failed to read embedded vts script: %v", err) - } - - // Write the script content to the temporary file - if _, err := tmpFile.Write(scriptContent); err != nil { - return fmt.Errorf("failed to write vts script to temporary file: %v", err) - } - tmpFile.Close() - - // Make the temporary file executable - if err := os.Chmod(tmpFile.Name(), 0755); err != nil { - return fmt.Errorf("failed to make temporary file executable: %v", err) - } - - // Execute the script - cmdArgs := append([]string{tmpFile.Name(), command}, args...) - cmd := exec.Command("bash", cmdArgs...) - - // Set up pipes for stdin, stdout, and stderr - cmd.Stdin = os.Stdin - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - - // Run the command and wait for it to finish - return cmd.Run() + // Create a temporary file to store the vts script + tmpFile, err := os.CreateTemp("", "vts-script") + if err != nil { + return fmt.Errorf("failed to create temporary file: %v", err) + } + defer os.Remove(tmpFile.Name()) + + // Read the embedded vts script + scriptContent, err := vtsScript.ReadFile("vts") + if err != nil { + return fmt.Errorf("failed to read embedded vts script: %v", err) + } + + // Write the script content to the temporary file + if _, err := tmpFile.Write(scriptContent); err != nil { + return fmt.Errorf("failed to write vts script to temporary file: %v", err) + } + tmpFile.Close() + + // Make the temporary file executable + if err := os.Chmod(tmpFile.Name(), 0755); err != nil { + return fmt.Errorf("failed to make temporary file executable: %v", err) + } + + // Execute the script + cmdArgs := append([]string{tmpFile.Name(), command}, args...) + cmd := exec.Command("bash", cmdArgs...) + + // Set up pipes for stdin, stdout, and stderr + cmd.Stdin = os.Stdin + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + + // Run the command and wait for it to finish + return cmd.Run() +} + +func registerAgent(controlPlaneURL, publicKey string) error { + hostname, err := os.Hostname() + if err != nil { + return fmt.Errorf("failed to get hostname: %v", err) + } + + data := map[string]string{ + "hostname": hostname, + "public_key": publicKey, + } + + jsonData, err := json.Marshal(data) + if err != nil { + return fmt.Errorf("failed to marshal JSON: %v", err) + } + + resp, err := http.Post(controlPlaneURL+"/register", "application/json", bytes.NewBuffer(jsonData)) + if err != nil { + return fmt.Errorf("failed to send registration request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + body, _ := ioutil.ReadAll(resp.Body) + return fmt.Errorf("registration failed with status %d: %s", resp.StatusCode, string(body)) + } + + fmt.Println("Successfully registered with control plane") + return nil }