diff --git a/go-workspace/src/cmd/entrypoint/admin.go b/go-workspace/src/cmd/entrypoint/admin.go new file mode 100644 index 0000000..773031f --- /dev/null +++ b/go-workspace/src/cmd/entrypoint/admin.go @@ -0,0 +1,112 @@ +package entrypoint + +import ( + "cryptic-net/admin" + "cryptic-net/bootstrap" + "cryptic-net/nebula" + "errors" + "fmt" + "os" +) + +func readAdmin(path string) (admin.Admin, error) { + + if path == "-" { + + adm, err := admin.FromReader(os.Stdin) + if err != nil { + return admin.Admin{}, fmt.Errorf("parsing admin.tgz from stdin: %w", err) + } + + return adm, nil + } + + f, err := os.Open(path) + if err != nil { + return admin.Admin{}, fmt.Errorf("opening file: %w", err) + } + defer f.Close() + + return admin.FromReader(f) +} + +var subCmdAdminMakeBootstrap = subCmd{ + name: "make-bootstrap", + descr: "Creates a new bootstrap.tgz file for a particular host and writes it to stdout", + checkLock: true, + do: func(subCmdCtx subCmdCtx) error { + + flags := subCmdCtx.flagSet(false) + + name := flags.StringP( + "name", "n", "", + "Name of the host to generate bootstrap.tgz for", + ) + + adminPath := flags.StringP( + "admin-path", "a", "", + `Path to admin.tgz file. If the given path is "-" then stdin is used.`, + ) + + if err := flags.Parse(subCmdCtx.args); err != nil { + return fmt.Errorf("parsing flags: %w", err) + } + + if *name == "" || *adminPath == "" { + return errors.New("--name and --admin-path are required") + } + + env := subCmdCtx.env + + adm, err := readAdmin(*adminPath) + if err != nil { + return fmt.Errorf("reading admin.tgz with --admin-path of %q: %w", *adminPath, err) + } + + client, err := env.Bootstrap.GlobalBucketS3APIClient() + if err != nil { + return fmt.Errorf("creating client for global bucket: %w", err) + } + + // NOTE this isn't _technically_ required, but if the `hosts add` + // command for this host has been run recently then it might not have + // made it into the bootstrap file yet, and so won't be in + // `env.Bootstrap`. + hosts, err := bootstrap.GetGarageBootstrapHosts(env.Context, client) + if err != nil { + return fmt.Errorf("retrieving host info from garage: %w", err) + } + + host, ok := hosts[*name] + if !ok { + return fmt.Errorf("couldn't find host into for %q in garage, has `cryptic-net hosts add` been run yet?", *name) + } + + nebulaHostCert, err := nebula.NewHostCert(adm.NebulaCACert, host.Name, host.Nebula.IP) + if err != nil { + return fmt.Errorf("creating new nebula host key/cert: %w", err) + } + + newBootstrap := bootstrap.Bootstrap{ + Hosts: hosts, + HostName: *name, + + NebulaHostCert: nebulaHostCert, + + GarageRPCSecret: adm.GarageRPCSecret, + GarageGlobalBucketS3APICredentials: adm.GarageGlobalBucketS3APICredentials, + } + + return newBootstrap.WriteTo(os.Stdout) + }, +} + +var subCmdAdmin = subCmd{ + name: "admin", + descr: "Sub-commands which only admins can run", + do: func(subCmdCtx subCmdCtx) error { + return subCmdCtx.doSubCmd( + subCmdAdminMakeBootstrap, + ) + }, +} diff --git a/go-workspace/src/cmd/entrypoint/hosts.go b/go-workspace/src/cmd/entrypoint/hosts.go index e308098..235365a 100644 --- a/go-workspace/src/cmd/entrypoint/hosts.go +++ b/go-workspace/src/cmd/entrypoint/hosts.go @@ -1,9 +1,7 @@ package entrypoint import ( - "cryptic-net/admin" "cryptic-net/bootstrap" - "cryptic-net/nebula" "errors" "fmt" "net" @@ -140,107 +138,14 @@ var subCmdHostsDelete = subCmd{ }, } -func readAdmin(path string) (admin.Admin, error) { - - if path == "-" { - - adm, err := admin.FromReader(os.Stdin) - if err != nil { - return admin.Admin{}, fmt.Errorf("parsing admin.tgz from stdin: %w", err) - } - - return adm, nil - } - - f, err := os.Open(path) - if err != nil { - return admin.Admin{}, fmt.Errorf("opening file: %w", err) - } - defer f.Close() - - return admin.FromReader(f) -} - -var subCmdHostsMakeBootstrap = subCmd{ - name: "make-bootstrap", - descr: "Creates a new bootstrap.tgz file for a particular host and writes it to stdout", - checkLock: true, - do: func(subCmdCtx subCmdCtx) error { - - flags := subCmdCtx.flagSet(false) - - name := flags.StringP( - "name", "n", "", - "Name of the host to generate bootstrap.tgz for", - ) - - adminPath := flags.StringP( - "admin-path", "a", "", - `Path to admin.tgz file. If the given path is "-" then stdin is used.`, - ) - - if err := flags.Parse(subCmdCtx.args); err != nil { - return fmt.Errorf("parsing flags: %w", err) - } - - if *name == "" || *adminPath == "" { - return errors.New("--name and --admin-path are required") - } - - env := subCmdCtx.env - - adm, err := readAdmin(*adminPath) - if err != nil { - return fmt.Errorf("reading admin.tgz with --admin-path of %q: %w", *adminPath, err) - } - - client, err := env.Bootstrap.GlobalBucketS3APIClient() - if err != nil { - return fmt.Errorf("creating client for global bucket: %w", err) - } - - // NOTE this isn't _technically_ required, but if the `hosts add` - // command for this host has been run recently then it might not have - // made it into the bootstrap file yet, and so won't be in - // `env.Bootstrap`. - hosts, err := bootstrap.GetGarageBootstrapHosts(env.Context, client) - if err != nil { - return fmt.Errorf("retrieving host info from garage: %w", err) - } - - host, ok := hosts[*name] - if !ok { - return fmt.Errorf("couldn't find host into for %q in garage, has `cryptic-net hosts add` been run yet?", *name) - } - - nebulaHostCert, err := nebula.NewHostCert(adm.NebulaCACert, host.Name, host.Nebula.IP) - if err != nil { - return fmt.Errorf("creating new nebula host key/cert: %w", err) - } - - newBootstrap := bootstrap.Bootstrap{ - Hosts: hosts, - HostName: *name, - - NebulaHostCert: nebulaHostCert, - - GarageRPCSecret: adm.GarageRPCSecret, - GarageGlobalBucketS3APICredentials: adm.GarageGlobalBucketS3APICredentials, - } - - return newBootstrap.WriteTo(os.Stdout) - }, -} - var subCmdHosts = subCmd{ name: "hosts", descr: "Sub-commands having to do with configuration of hosts in the network", do: func(subCmdCtx subCmdCtx) error { return subCmdCtx.doSubCmd( subCmdHostsAdd, - subCmdHostsList, subCmdHostsDelete, - subCmdHostsMakeBootstrap, + subCmdHostsList, ) }, } diff --git a/go-workspace/src/cmd/entrypoint/main.go b/go-workspace/src/cmd/entrypoint/main.go index c502280..ad6e254 100644 --- a/go-workspace/src/cmd/entrypoint/main.go +++ b/go-workspace/src/cmd/entrypoint/main.go @@ -24,9 +24,10 @@ func Main() { args: os.Args[1:], env: env, }.doSubCmd( + subCmdAdmin, subCmdDaemon, - subCmdHosts, subCmdGarage, + subCmdHosts, subCmdVersion, )