go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/apps/cnquery/cmd/logout.go (about) 1 // Copyright (c) Mondoo, Inc. 2 // SPDX-License-Identifier: BUSL-1.1 3 4 package cmd 5 6 import ( 7 "context" 8 "os" 9 10 "github.com/rs/zerolog/log" 11 "github.com/spf13/cobra" 12 "github.com/spf13/viper" 13 "go.mondoo.com/cnquery/cli/config" 14 "go.mondoo.com/cnquery/cli/sysinfo" 15 "go.mondoo.com/cnquery/providers-sdk/v1/upstream" 16 "sigs.k8s.io/yaml" 17 ) 18 19 func init() { 20 rootCmd.AddCommand(LogoutCmd) 21 LogoutCmd.Flags().Bool("force", false, "Force re-authentication") 22 } 23 24 var LogoutCmd = &cobra.Command{ 25 Use: "logout", 26 Aliases: []string{"unregister"}, 27 Short: "Log out from Mondoo Platform.", 28 Long: ` 29 This process also revokes the Mondoo Platform service account to 30 ensure the credentials cannot be used in the future. 31 `, 32 PreRun: func(cmd *cobra.Command, args []string) { 33 viper.BindPFlag("force", cmd.Flags().Lookup("force")) 34 }, 35 Run: func(cmd *cobra.Command, args []string) { 36 var err error 37 38 // its perfectly fine not to have a config here, therefore we ignore errors 39 opts, optsErr := config.Read() 40 if optsErr != nil { 41 log.Fatal().Msg("could not load configuration") 42 } 43 44 // print the used config to the user 45 config.DisplayUsedConfig() 46 47 // determine information about the client 48 sysInfo, err := sysinfo.GatherSystemInfo() 49 if err != nil { 50 log.Fatal().Err(err).Msg("could not gather client information") 51 } 52 53 // check valid client authentication 54 serviceAccount := opts.GetServiceCredential() 55 if serviceAccount == nil { 56 log.Error().Err(err).Msg("could not initialize client authentication") 57 os.Exit(ConfigurationErrorCode) 58 } 59 60 plugins := defaultRangerPlugins(sysInfo, opts.GetFeatures()) 61 certAuth, err := upstream.NewServiceAccountRangerPlugin(serviceAccount) 62 if err != nil { 63 log.Error().Err(err).Msg("could not initialize client authentication") 64 os.Exit(ConfigurationErrorCode) 65 } 66 plugins = append(plugins, certAuth) 67 68 httpClient, err := opts.GetHttpClient() 69 if err != nil { 70 log.Fatal().Err(err).Msg("error while creating Mondoo API client") 71 } 72 client, err := upstream.NewAgentManagerClient(opts.UpstreamApiEndpoint(), httpClient, plugins...) 73 if err != nil { 74 log.Error().Err(err).Msg("could not initialize connection to Mondoo Platform") 75 os.Exit(ConfigurationErrorCode) 76 } 77 78 if !viper.GetBool("force") { 79 log.Info().Msg("are you sure you want to revoke client access to Mondoo Platform? Use --force if you are sure") 80 os.Exit(1) 81 return 82 } 83 84 // try to load config into credentials struct 85 credentials := opts.GetServiceCredential() 86 87 // if we have credentials, we are going to self-destroy 88 ctx := context.Background() 89 if credentials != nil && len(credentials.Mrn) > 0 { 90 _, err = client.PingPong(ctx, &upstream.Ping{}) 91 92 if err == nil { 93 log.Info().Msgf("client %s authenticated successfully", credentials.Mrn) 94 95 // un-register the agent 96 _, err = client.UnRegisterAgent(ctx, &upstream.Mrn{ 97 Mrn: opts.AgentMrn, 98 }) 99 if err != nil { 100 log.Error().Err(err).Msg("failed to unregister client") 101 } 102 } else { 103 log.Error().Err(err).Msg("communication with Mondoo Platform failed") 104 } 105 } 106 107 // delete config if it exists 108 path := viper.ConfigFileUsed() 109 fi, err := os.Stat(path) 110 if err == nil { 111 log.Debug().Str("path", path).Msg("remove client information from config") 112 113 opts.AgentMrn = "" 114 115 data, err := yaml.Marshal(opts) 116 if err != nil { 117 log.Error().Err(err).Msg("could not update Mondoo config") 118 } 119 err = os.WriteFile(path, data, fi.Mode()) 120 if err != nil { 121 log.Error().Err(err).Msg("could not update Mondoo config") 122 } 123 } 124 125 log.Info().Msgf("Bye bye, space cat. Client %s unregistered successfully", credentials.Mrn) 126 }, 127 }