diff --git a/cmd/agent/main.go b/cmd/agent/main.go index 9a6a0f8..754b2d8 100644 --- a/cmd/agent/main.go +++ b/cmd/agent/main.go @@ -10,13 +10,10 @@ import ( agent "github.com/c3os-io/c3os/internal/agent" "github.com/c3os-io/c3os/internal/bus" - cmd "github.com/c3os-io/c3os/internal/cmd" - providerConfig "github.com/c3os-io/c3os/internal/provider/config" machine "github.com/c3os-io/c3os/pkg/machine" bundles "github.com/c3os-io/c3os/sdk/bundles" "github.com/c3os-io/c3os/internal/github" - config "github.com/c3os-io/c3os/pkg/config" "github.com/urfave/cli" "gopkg.in/yaml.v2" ) @@ -183,70 +180,6 @@ E.g. c3os-agent install-bundle container:quay.io/c3os/c3os... return bundles.RunBundles([]bundles.BundleOption{bundles.WithRepository(c.String("repository")), bundles.WithTarget(args[0])}) }, }, - { - Name: "rotate", - Usage: "Rotate a c3os node network configuration via CLI", - Description: ` - -Updates a c3os node VPN configuration. - -For example, to update the network token in a node: -$ c3os rotate --network-token XXX -`, - Aliases: []string{"r"}, - Flags: []cli.Flag{ - &cli.BoolFlag{ - Name: "restart", - }, - &cli.StringFlag{ - Name: "network-token", - EnvVar: "NETWORK_TOKEN", - }, - &cli.StringFlag{ - Name: "api", - Value: "127.0.0.1:8080", - }, - &cli.StringFlag{ - Name: "root-dir", - }, - }, - UsageText: "Rotate network token manually in the node", - Action: func(c *cli.Context) error { - dirs := []string{"/oem", "/usr/local/cloud-config"} - args := c.Args() - if len(args) > 0 { - dirs = args - } - - return agent.RotateToken(dirs, c.String("network-token"), c.String("api"), c.String("root-dir"), c.Bool("restart")) - }, - }, - - { - Name: "get-network-token", - Description: "Print network token from local configuration", - Usage: "Print network token from local configuration", - Action: func(c *cli.Context) error { - dirs := []string{"/oem", "/usr/local/cloud-config"} - args := c.Args() - if len(args) > 0 { - dirs = args - } - cc, err := config.Scan(config.Directories(dirs...)) - if err != nil { - return err - } - - providerCfg := &providerConfig.Config{} - err = cc.Unmarshal(providerCfg) - if err != nil { - return err - } - - fmt.Print(providerCfg.C3OS.NetworkToken) - return nil - }, - }, { Name: "uuid", Usage: "Prints the local UUID", @@ -352,7 +285,7 @@ For all the example cases, see: https://docs.c3os.io . UsageText: ``, Copyright: "Ettore Di Giacinto", - Commands: cmd.CommonCommand(cmds...), + Commands: cmds, } err := app.Run(os.Args) diff --git a/cmd/cli/bridge.go b/cmd/cli/bridge.go deleted file mode 100644 index 3754390..0000000 --- a/cmd/cli/bridge.go +++ /dev/null @@ -1,118 +0,0 @@ -package main - -import ( - "context" - "fmt" - "net" - "time" - - "github.com/c3os-io/c3os/pkg/config" - "github.com/c3os-io/c3os/pkg/utils" - "github.com/ipfs/go-log" - "github.com/mudler/edgevpn/api" - "github.com/mudler/edgevpn/pkg/logger" - "github.com/mudler/edgevpn/pkg/node" - "github.com/mudler/edgevpn/pkg/services" - "github.com/mudler/edgevpn/pkg/vpn" - qr "github.com/mudler/go-nodepair/qrcode" - "github.com/urfave/cli" -) - -// bridge is just starting a VPN with edgevpn to the given network token. -func bridge(c *cli.Context) error { - qrCodePath := "" - fromQRCode := false - var serviceUUID, sshPassword string - - if c.String("qr-code-image") != "" { - qrCodePath = c.String("qr-code-image") - fromQRCode = true - } - if c.Bool("qr-code-snapshot") { - qrCodePath = "" - fromQRCode = true - } - - token := c.String("network-token") - - if fromQRCode { - recoveryToken := qr.Reader(qrCodePath) - data := utils.DecodeRecoveryToken(recoveryToken) - if len(data) != 3 { - fmt.Println("Token not decoded correctly") - return fmt.Errorf("invalid token") - } - token = data[0] - serviceUUID = data[1] - sshPassword = data[2] - if serviceUUID == "" || sshPassword == "" || token == "" { - return fmt.Errorf("decoded invalid values") - } - } - - ctx := context.Background() - - nc := config.Network(token, c.String("address"), c.String("log-level"), "c3os0") - - lvl, err := log.LevelFromString(nc.LogLevel) - if err != nil { - lvl = log.LevelError - } - llger := logger.New(lvl) - - o, vpnOpts, err := nc.ToOpts(llger) - if err != nil { - llger.Fatal(err.Error()) - } - - opts := []node.Option{} - - if !fromQRCode { - // We just connect to a VPN token - o = append(o, - services.Alive( - time.Duration(20)*time.Second, - time.Duration(10)*time.Second, - time.Duration(10)*time.Second)...) - - if c.Bool("dhcp") { - // Adds DHCP server - address, _, err := net.ParseCIDR(c.String("address")) - if err != nil { - return err - } - nodeOpts, vO := vpn.DHCP(llger, 15*time.Minute, c.String("lease-dir"), address.String()) - o = append(o, nodeOpts...) - vpnOpts = append(vpnOpts, vO...) - } - - opts, err = vpn.Register(vpnOpts...) - if err != nil { - return err - } - } else { - // We hook into a service - llger.Info("Connecting to service", serviceUUID) - llger.Info("SSH access password is", sshPassword) - llger.Info("SSH server reachable at 127.0.0.1:2200") - opts = append(opts, node.WithNetworkService( - services.ConnectNetworkService( - 30*time.Second, - serviceUUID, - "127.0.0.1:2200", - ), - )) - llger.Info("To connect, keep this terminal open and run in another terminal 'ssh 127.0.0.1 -p 2200' the password is ", sshPassword) - llger.Info("Note: the connection might not be available instantly and first attempts will likely fail.") - llger.Info(" Few attempts might be required before establishing a tunnel to the host.") - } - - e, err := node.New(append(o, opts...)...) - if err != nil { - return err - } - - go api.API(ctx, c.String("api"), 5*time.Second, 20*time.Second, e, nil, false) //nolint:errcheck - - return e.Start(ctx) -} diff --git a/cmd/cli/main.go b/cmd/cli/main.go deleted file mode 100644 index 4b5bb85..0000000 --- a/cmd/cli/main.go +++ /dev/null @@ -1,179 +0,0 @@ -package main - -import ( - "fmt" - "os" - - cmd "github.com/c3os-io/c3os/internal/cmd" - - "github.com/urfave/cli" -) - -var cliCmd = []cli.Command{ - { - Name: "register", - UsageText: "register --reboot --device /dev/sda /image/snapshot.png", - Usage: "Registers and bootstraps a node", - Description: ` -Bootstraps a node which is started in pairing mode. It can send over a configuration file used to install the c3os node. - -For example: -$ c3os register --config config.yaml --device /dev/sda ~/Downloads/screenshot.png - -will decode the QR code from ~/Downloads/screenshot.png and bootstrap the node remotely. - -If the image is omitted, a screenshot will be taken and used to decode the QR code. - -See also https://docs.c3os.io/installation/device_pairing/ for documentation. -`, - ArgsUsage: "Register optionally accepts an image. If nothing is passed will take a screenshot of the screen and try to decode the QR code", - Flags: []cli.Flag{ - &cli.StringFlag{ - Name: "config", - Usage: "C3OS YAML configuration file", - }, - &cli.StringFlag{ - Name: "device", - Usage: "Device used for the installation target", - }, - &cli.BoolFlag{ - Name: "reboot", - Usage: "Reboot node after installation", - }, - &cli.BoolFlag{ - Name: "poweroff", - Usage: "Shutdown node after installation", - }, - &cli.StringFlag{ - Name: "log-level", - Usage: "Set log level", - }, - }, - - Action: func(c *cli.Context) error { - args := c.Args() - var ref string - if len(args) == 1 { - ref = args[0] - } - - return register(c.String("log-level"), ref, c.String("config"), c.String("device"), c.Bool("reboot"), c.Bool("poweroff")) - }, - }, - { - Name: "bridge", - UsageText: "bridge --network-token XXX", - Usage: "Connect to a c3os VPN network", - Description: ` -Starts a bridge with a c3os network or a node. - -# With a network - -By default, "bridge" will create a VPN network connection to the node with the token supplied, thus it requires elevated permissions in order to work. - -For example: - -$ sudo c3os bridge --network-token - -Will start a VPN, which local ip is fixed to 10.1.0.254 (tweakable with --address). - -The API will also be accessible at http://127.0.0.1:8080 - -# With a node - -"c3os bridge" can be used also to connect over to a node in recovery mode. When operating in this modality c3os bridge requires no specific permissions, indeed a tunnel -will be created locally to connect to the machine remotely. - -For example: - -$ c3os bridge --qr-code-image /path/to/image.png - -Will scan the QR code in the image and connect over. Further instructions on how to connect over will be printed out to the screen. - -See also: https://docs.c3os.io/after_install/troubleshooting/#connect-to-the-cluster-network and https://docs.c3os.io/after_install/recovery_mode/ - -`, - Flags: []cli.Flag{ - &cli.StringFlag{ - Name: "network-token", - Required: false, - EnvVar: "NETWORK_TOKEN", - Usage: "Network token to connect over", - }, - &cli.StringFlag{ - Name: "log-level", - Required: false, - EnvVar: "LOGLEVEL", - Value: "info", - Usage: "Bridge log level", - }, - &cli.BoolFlag{ - Name: "qr-code-snapshot", - Required: false, - Usage: "Bool to take a local snapshot instead of reading from an image file for recovery", - EnvVar: "QR_CODE_SNAPSHOT", - }, - &cli.StringFlag{ - Name: "qr-code-image", - Usage: "Path to an image containing a valid QR code for recovery mode", - Required: false, - EnvVar: "QR_CODE_IMAGE", - }, - &cli.StringFlag{ - Name: "api", - Value: "127.0.0.1:8080", - Usage: "Listening API url", - }, - &cli.BoolFlag{ - Name: "dhcp", - EnvVar: "DHCP", - Usage: "Enable DHCP", - }, - &cli.StringFlag{ - Value: "10.1.0.254/24", - Name: "address", - EnvVar: "ADDRESS", - Usage: "Specify an address for the bridge", - }, - &cli.StringFlag{ - Value: "/tmp/c3os", - Name: "lease-dir", - EnvVar: "lease-dir", - Usage: "DHCP Lease directory", - }, - }, - Action: bridge, - }, -} - -func main() { - - app := &cli.App{ - Name: "c3os", - Version: "0.1", - Author: "Ettore Di Giacinto", - Usage: "c3os CLI to bootstrap, upgrade, connect and manage a c3os network", - Description: ` -The c3os CLI can be used to manage a c3os box and perform all day-two tasks, like: -- register a node -- connect to a node in recovery mode -- to establish a VPN connection -- set, list roles -- interact with the network API - -and much more. - -For all the example cases, see: https://docs.c3os.io . -`, - UsageText: ``, - Copyright: "Ettore Di Giacinto", - - Commands: cmd.CommonCommand(cliCmd...), - } - - err := app.Run(os.Args) - if err != nil { - fmt.Println(err) - os.Exit(1) - } -} diff --git a/cmd/cli/register.go b/cmd/cli/register.go deleted file mode 100644 index 435b238..0000000 --- a/cmd/cli/register.go +++ /dev/null @@ -1,46 +0,0 @@ -package main - -import ( - "context" - "fmt" - "io/ioutil" - - nodepair "github.com/mudler/go-nodepair" - qr "github.com/mudler/go-nodepair/qrcode" -) - -func register(loglevel, arg, configFile, device string, reboot, poweroff bool) error { - b, _ := ioutil.ReadFile(configFile) - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - // dmesg -D to suppress tty ev - fmt.Println("Sending registration payload, please wait") - - config := map[string]string{ - "device": device, - "cc": string(b), - } - - if reboot { - config["reboot"] = "" - } - - if poweroff { - config["poweroff"] = "" - } - - err := nodepair.Send( - ctx, - config, - nodepair.WithReader(qr.Reader), - nodepair.WithToken(arg), - nodepair.WithLogLevel(loglevel), - ) - if err != nil { - return err - } - - fmt.Println("Payload sent, installation will start on the machine briefly") - return nil -}