Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨Run status check on login errors #4325

Merged
merged 5 commits into from
Jul 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion apps/cnquery/cmd/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,17 @@ You remain logged in until you explicitly log out using the 'logout' subcommand.
annotations, _ := cmd.Flags().GetStringToString("annotation")
timer, _ := cmd.Flags().GetInt("timer")
splay, _ := cmd.Flags().GetInt("splay")
return register(token, annotations, timer, splay)
err := register(token, annotations, timer, splay)
if err != nil {
defer func() {
s, err := checkStatus()
if err != nil {
log.Warn().Err(err).Msg("could not run status command")
}
s.RenderCliStatus()
}()
}
return err
},
}

Expand Down
144 changes: 77 additions & 67 deletions apps/cnquery/cmd/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,77 +44,12 @@ Status sends a ping to Mondoo Platform to verify the credentials.
},
RunE: func(cmd *cobra.Command, args []string) error {
defer providers.Coordinator.Shutdown()
opts, optsErr := config.Read()
if optsErr != nil {
return cli_errors.NewCommandError(errors.Wrap(optsErr, "could not load configuration"), 1)
}

config.DisplayUsedConfig()

s := Status{
Client: ClientStatus{
Timestamp: time.Now().Format(time.RFC3339),
Version: cnquery.GetVersion(),
Build: cnquery.GetBuild(),
},
}

httpClient, err := opts.GetHttpClient()
if err != nil {
return cli_errors.NewCommandError(errors.Wrap(err, "failed to set up Mondoo API client"), 1)
}

sysInfo, err := sysinfo.Get()
if err == nil {
s.Client.Platform = sysInfo.Platform
s.Client.Hostname = sysInfo.Hostname
s.Client.IP = sysInfo.IP
}

// check server health and clock skew
upstreamStatus, err := health.CheckApiHealth(httpClient, opts.UpstreamApiEndpoint())
s, err := checkStatus()
if err != nil {
log.Error().Err(err).Msg("could not check upstream health")
}
s.Upstream = upstreamStatus

latestVersion, err := cnquery.GetLatestVersion(httpClient)
if err != nil {
return cli_errors.NewCommandError(errors.Wrap(err, "failed to get latest version"), 1)
}

s.Client.LatestVersion = latestVersion

// check valid agent authentication
plugins := []ranger.ClientPlugin{}

// try to load config into credentials struct
credentials := opts.GetServiceCredential()
if credentials != nil && len(credentials.Mrn) > 0 {
s.Client.ParentMrn = credentials.ParentMrn
s.Client.Registered = true
s.Client.ServiceAccount = credentials.Mrn
s.Client.Mrn = opts.AgentMrn
if s.Client.Mrn == "" {
s.Client.Mrn = "no managed client"
}

certAuth, err := upstream.NewServiceAccountRangerPlugin(credentials)
if err != nil {
return cli_errors.NewCommandError(errors.Wrap(err, "invalid credentials"), ConfigurationErrorCode)
}
plugins = append(plugins, certAuth)

// try to ping the server
client, err := upstream.NewAgentManagerClient(s.Upstream.API.Endpoint, httpClient, plugins...)
if err == nil {
_, err = client.PingPong(context.Background(), &upstream.Ping{})
if err != nil {
s.Client.PingPongError = err
}
} else {
s.Client.PingPongError = err
}
return err
}

switch strings.ToLower(viper.GetString("output")) {
Expand All @@ -135,6 +70,81 @@ Status sends a ping to Mondoo Platform to verify the credentials.
},
}

func checkStatus() (Status, error) {
s := Status{
Client: ClientStatus{
Timestamp: time.Now().Format(time.RFC3339),
Version: cnquery.GetVersion(),
Build: cnquery.GetBuild(),
},
}

opts, optsErr := config.Read()
if optsErr != nil {
return s, cli_errors.NewCommandError(errors.Wrap(optsErr, "could not load configuration"), 1)
}

httpClient, err := opts.GetHttpClient()
if err != nil {
return s, cli_errors.NewCommandError(errors.Wrap(err, "failed to set up Mondoo API client"), 1)
}

sysInfo, err := sysinfo.Get()
if err == nil {
s.Client.Platform = sysInfo.Platform
s.Client.Hostname = sysInfo.Hostname
s.Client.IP = sysInfo.IP
}

// check server health and clock skew
upstreamStatus, err := health.CheckApiHealth(httpClient, opts.UpstreamApiEndpoint())
if err != nil {
log.Error().Err(err).Msg("could not check upstream health")
}
s.Upstream = upstreamStatus

latestVersion, err := cnquery.GetLatestVersion(httpClient)
if err != nil {
return s, cli_errors.NewCommandError(errors.Wrap(err, "failed to get latest version"), 1)
}

s.Client.LatestVersion = latestVersion

// check valid agent authentication
plugins := []ranger.ClientPlugin{}

// try to load config into credentials struct
credentials := opts.GetServiceCredential()
if credentials != nil && len(credentials.Mrn) > 0 {
s.Client.ParentMrn = credentials.GetParentMrn()
s.Client.Registered = true
s.Client.ServiceAccount = credentials.Mrn
s.Client.Mrn = opts.AgentMrn
if s.Client.Mrn == "" {
s.Client.Mrn = "no managed client"
}

certAuth, err := upstream.NewServiceAccountRangerPlugin(credentials)
if err != nil {
return s, cli_errors.NewCommandError(errors.Wrap(err, "invalid credentials"), ConfigurationErrorCode)
}
plugins = append(plugins, certAuth)

// try to ping the server
client, err := upstream.NewAgentManagerClient(s.Upstream.API.Endpoint, httpClient, plugins...)
if err == nil {
_, err = client.PingPong(context.Background(), &upstream.Ping{})
if err != nil {
s.Client.PingPongError = err
}
} else {
s.Client.PingPongError = err
}
}

return s, nil
}

type Status struct {
Client ClientStatus `json:"client"`
Upstream health.Status `json:"upstream"`
Expand Down
Loading