mirror of
https://github.com/turbot/steampipe.git
synced 2026-02-18 13:00:10 -05:00
321 lines
8.0 KiB
Go
321 lines
8.0 KiB
Go
package cmd
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/spf13/cobra"
|
|
"github.com/turbot/go-kit/helpers"
|
|
"github.com/turbot/steampipe-plugin-sdk/logging"
|
|
|
|
"github.com/turbot/steampipe/cmdconfig"
|
|
"github.com/turbot/steampipe/constants"
|
|
"github.com/turbot/steampipe/db"
|
|
"github.com/turbot/steampipe/utils"
|
|
)
|
|
|
|
// ServiceCmd :: Service management commands
|
|
func ServiceCmd() *cobra.Command {
|
|
var cmd = &cobra.Command{
|
|
Use: "service [command]",
|
|
Args: cobra.NoArgs,
|
|
Short: "Steampipe service management",
|
|
// TODO(nw) expand long description
|
|
Long: `Steampipe service management.
|
|
|
|
Run Steampipe as a local service, exposing it as a database endpoint for
|
|
connection from any Postgres compatible database client.`,
|
|
}
|
|
|
|
cmd.AddCommand(ServiceStartCmd())
|
|
cmd.AddCommand(ServiceStatusCmd())
|
|
cmd.AddCommand(ServiceStopCmd())
|
|
cmd.AddCommand(ServiceRestartCmd())
|
|
|
|
return cmd
|
|
}
|
|
|
|
// ServiceStartCmd :: handler for service start
|
|
func ServiceStartCmd() *cobra.Command {
|
|
var cmd = &cobra.Command{
|
|
Use: "start",
|
|
Args: cobra.NoArgs,
|
|
Run: runServiceStartCmd,
|
|
Short: "Start Steampipe in service mode",
|
|
Long: `Start the Steampipe service.
|
|
|
|
Run Steampipe as a local service, exposing it as a database endpoint for
|
|
connection from any Postgres compatible database client.`,
|
|
}
|
|
|
|
cmdconfig.
|
|
OnCmd(cmd).
|
|
AddBoolFlag(constants.ArgBackground, "", true, "Run service in the background").
|
|
// for now default port to -1 so we fall back to the default of the deprecated arg
|
|
AddIntFlag(constants.ArgPort, "", -1, "Database service port.").
|
|
AddIntFlag(constants.ArgPortDeprecated, "", constants.DatabasePort, "Database service port.", cmdconfig.FlagOptions.Deprecated(constants.ArgPort)).
|
|
// for now default listen address to empty so we fall back to the default of the deprecated arg
|
|
AddStringFlag(constants.ArgListenAddress, "", "", "Accept connections from: local (localhost only) or network (open)").
|
|
AddStringFlag(constants.ArgListenAddressDeprecated, "", string(db.ListenTypeNetwork), "Accept connections from: local (localhost only) or network (open)", cmdconfig.FlagOptions.Deprecated(constants.ArgListenAddress)).
|
|
// Hidden flags for internal use
|
|
AddStringFlag(constants.ArgInvoker, "", string(db.InvokerService), "Invoked by \"service\" or \"query\"", cmdconfig.FlagOptions.Hidden()).
|
|
AddBoolFlag(constants.ArgRefresh, "", true, "Refresh connections on startup", cmdconfig.FlagOptions.Hidden())
|
|
|
|
return cmd
|
|
}
|
|
|
|
// ServiceStatusCmd :: handler for service status
|
|
func ServiceStatusCmd() *cobra.Command {
|
|
var cmd = &cobra.Command{
|
|
Use: "status",
|
|
Args: cobra.NoArgs,
|
|
Run: runServiceStatusCmd,
|
|
Short: "Status of the Steampipe service",
|
|
Long: `Status of the Steampipe service.
|
|
|
|
Report current status of the Steampipe database service.`,
|
|
}
|
|
|
|
cmdconfig.OnCmd(cmd)
|
|
|
|
return cmd
|
|
}
|
|
|
|
// ServiceStopCmd :: handler for service stop
|
|
func ServiceStopCmd() *cobra.Command {
|
|
cmd := &cobra.Command{
|
|
Use: "stop",
|
|
Args: cobra.NoArgs,
|
|
Run: runServiceStopCmd,
|
|
Short: "Stop Steampipe service",
|
|
Long: `Stop the Steampipe service.`,
|
|
}
|
|
|
|
cmdconfig.
|
|
OnCmd(cmd).
|
|
AddBoolFlag(constants.ArgForce, "", false, "Forces the service to shutdown, releasing all open connections and ports")
|
|
|
|
return cmd
|
|
}
|
|
|
|
// ServiceRestartCmd :: restarts the database service
|
|
func ServiceRestartCmd() *cobra.Command {
|
|
var cmd = &cobra.Command{
|
|
Use: "restart",
|
|
Args: cobra.NoArgs,
|
|
Run: runServiceRestartCmd,
|
|
Short: "Restart Steampipe service",
|
|
Long: `Restart the Steampipe service.`,
|
|
}
|
|
|
|
cmdconfig.
|
|
OnCmd(cmd).
|
|
AddBoolFlag(constants.ArgForce, "", false, "Forces the service to restart, releasing all open connections and ports")
|
|
|
|
return cmd
|
|
}
|
|
|
|
func runServiceStartCmd(cmd *cobra.Command, args []string) {
|
|
logging.LogTime("runServiceStartCmd start")
|
|
defer func() {
|
|
logging.LogTime("runServiceStartCmd end")
|
|
if r := recover(); r != nil {
|
|
utils.ShowError(helpers.ToError(r))
|
|
os.Exit(-1)
|
|
}
|
|
}()
|
|
|
|
port := cmdconfig.DatabasePort()
|
|
if port < 1 || port > 65535 {
|
|
fmt.Println("Invalid Port :: MUST be within range (1:65535)")
|
|
}
|
|
|
|
listen := db.StartListenType(cmdconfig.ListenAddress())
|
|
if err := listen.IsValid(); err != nil {
|
|
utils.ShowError(err)
|
|
return
|
|
}
|
|
|
|
invoker := db.Invoker(cmdconfig.Viper().GetString(constants.ArgInvoker))
|
|
if err := invoker.IsValid(); err != nil {
|
|
utils.ShowError(err)
|
|
return
|
|
}
|
|
|
|
db.EnsureDBInstalled()
|
|
|
|
status, err := db.StartDB(cmdconfig.DatabasePort(), listen, invoker)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
if status == db.ServiceFailedToStart {
|
|
panic(fmt.Errorf("Steampipe service failed to start"))
|
|
}
|
|
|
|
if status == db.ServiceAlreadyRunning {
|
|
panic(fmt.Errorf("Steampipe service is already running"))
|
|
}
|
|
|
|
info, _ := db.GetStatus()
|
|
|
|
printStatus(info)
|
|
|
|
}
|
|
|
|
func runServiceRestartCmd(cmd *cobra.Command, args []string) {
|
|
logging.LogTime("runServiceRestartCmd start")
|
|
defer func() {
|
|
logging.LogTime("runServiceRestartCmd end")
|
|
if r := recover(); r != nil {
|
|
utils.ShowError(helpers.ToError(r))
|
|
}
|
|
}()
|
|
|
|
currentServiceStatus, err := db.GetStatus()
|
|
|
|
if err != nil {
|
|
utils.ShowError(errors.New("could not retrieve service status"))
|
|
return
|
|
}
|
|
|
|
if currentServiceStatus == nil {
|
|
fmt.Println("steampipe database service is not running")
|
|
return
|
|
}
|
|
|
|
stopStatus, err := db.StopDB(cmdconfig.Viper().GetBool(constants.ArgForce), db.InvokerService)
|
|
|
|
if err != nil {
|
|
utils.ShowErrorWithMessage(err, "could not stop current instance")
|
|
return
|
|
}
|
|
|
|
if stopStatus != db.ServiceStopped {
|
|
fmt.Println(`
|
|
Service stop failed.
|
|
|
|
Try using:
|
|
steampipe service restart --force
|
|
|
|
to force a restart.
|
|
`)
|
|
return
|
|
}
|
|
|
|
status, err := db.StartDB(currentServiceStatus.Port, currentServiceStatus.ListenType, currentServiceStatus.Invoker)
|
|
if err != nil {
|
|
utils.ShowError(err)
|
|
return
|
|
}
|
|
|
|
if status == db.ServiceFailedToStart {
|
|
fmt.Println("Steampipe service was stopped, but failed to start")
|
|
return
|
|
}
|
|
|
|
fmt.Println("Steampipe service restarted")
|
|
|
|
if info, err := db.GetStatus(); err != nil {
|
|
printStatus(info)
|
|
}
|
|
|
|
}
|
|
|
|
func runServiceStatusCmd(cmd *cobra.Command, args []string) {
|
|
logging.LogTime("runServiceStatusCmd status")
|
|
defer func() {
|
|
logging.LogTime("runServiceStatusCmd end")
|
|
if r := recover(); r != nil {
|
|
utils.ShowError(helpers.ToError(r))
|
|
}
|
|
}()
|
|
|
|
if !db.IsInstalled() {
|
|
fmt.Println("Steampipe database service is NOT installed")
|
|
} else {
|
|
if info, err := db.GetStatus(); err != nil {
|
|
utils.ShowError(fmt.Errorf("Could not get Steampipe database service status"))
|
|
} else if info != nil {
|
|
printStatus(info)
|
|
} else {
|
|
fmt.Println("Steampipe database service is NOT running")
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
func printStatus(info *db.RunningDBInstanceInfo) {
|
|
|
|
msg := `
|
|
Steampipe database service is now running:
|
|
|
|
Host(s): %v
|
|
Port: %v
|
|
Database: %v
|
|
User: %v
|
|
Password: %v
|
|
|
|
Connection string:
|
|
|
|
postgres://%v:%v@%v:%v/%v?sslmode=disable
|
|
|
|
Steampipe service is running in the background.
|
|
|
|
# Get status of the service
|
|
steampipe service status
|
|
|
|
# Restart the service
|
|
steampipe service restart
|
|
|
|
# Stop the service
|
|
steampipe service stop
|
|
|
|
`
|
|
|
|
fmt.Printf(msg, strings.Join(info.Listen, ", "), info.Port, info.Database, info.User, info.Password, info.User, info.Password, info.Listen[0], info.Port, info.Database)
|
|
}
|
|
|
|
func runServiceStopCmd(cmd *cobra.Command, args []string) {
|
|
logging.LogTime("runServiceStopCmd stop")
|
|
defer func() {
|
|
logging.LogTime("runServiceStopCmd end")
|
|
if r := recover(); r != nil {
|
|
utils.ShowError(helpers.ToError(r))
|
|
}
|
|
}()
|
|
|
|
force := cmdconfig.Viper().GetBool(constants.ArgForce)
|
|
status, err := db.StopDB(force, db.InvokerService)
|
|
|
|
if err != nil {
|
|
utils.ShowError(err)
|
|
}
|
|
|
|
switch status {
|
|
case db.ServiceStopped:
|
|
fmt.Println("Steampipe database service stopped")
|
|
case db.ServiceStopFailed:
|
|
if err == nil {
|
|
fmt.Println("Could not stop service")
|
|
}
|
|
case db.ServiceNotRunning:
|
|
fmt.Println("Service is not running")
|
|
case db.ServiceStopTimedOut:
|
|
fmt.Println(`
|
|
Service stop operation timed-out.
|
|
|
|
This is probably because other clients are connected to the database service.
|
|
|
|
Disconnect all clients, or use
|
|
steampipe service stop --force
|
|
|
|
to force a shutdown
|
|
`)
|
|
|
|
}
|
|
|
|
}
|